]> SALOME platform Git repositories - tools/medcoupling.git/blobdiff - src/ParaMEDMEM/StructuredCoincidentDEC.cxx
Salome HOME
refactor!: remove adm_local/ directory
[tools/medcoupling.git] / src / ParaMEDMEM / StructuredCoincidentDEC.cxx
index 36454c959ff4b84b676dbca7c5ef1788da0500a3..89c0ce4c3635deaaf71815da6bbe86ed0243d647 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2024  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -34,89 +34,57 @@ using namespace std;
 namespace MEDCoupling
 {
 
-  /*!
-    \anchor StructuredCoincidentDEC-det
-    \class StructuredCoincidentDEC
-
-    This class aims at \ref interpolation "remapping fields" that have identical
-    structured supports (=the same underlying mesh) but different parallel topologies
-    (=different sub-domains in the structured mesh). It can be used to couple
-    together multi-physics codes that operate on the same domain
-    with different partitioning. This can be useful for example if one of
-    the computation is much faster than the other. It can also be used
-    to couple together codes that share an interface that was generated
-    in the same manner (with identical global ids).
-    Also, this \ref para-dec "DEC" can be used for fields that have component topologies,
-    i.e., components that are scattered over several processors.
-
-    The remapping between the two supports is based on identity of global
-    ids, instead of geometrical considerations (as it is the case for
-    \ref InterpKernelDEC-det "InterpKernelDEC").
-    Therefore, beware that this \ref para-dec "DEC" can not be used
-    for coincident meshes if they do *not* have the exact same numbering.
-
-    With this %DEC no projection, and no interpolation of the field data is done, contrary
-    to what happens in \ref InterpKernelDEC-det "InterpKernelDEC". It is just
-    a matter of allocating the values from one side to the other, using directly the cell
-    identifiers.
-
-    As all the other DECs, its usage requires two phases :
-    - a setup phase during which the topologies are exchanged so that
-    the target side knows from which processors it should expect
-    the data.
-    - a send/recv phase during which the field data is actually transferred.
-
-    This example illustrates the sending of a field with
-    the \c StructuredCoincidentDEC :
-    \code
-    ...
-    StructuredCoincidentDEC dec(groupA, groupB);
-    dec.attachLocalField(field);
-    dec.synchronize();
-    if (groupA.containsMyRank())
-    dec.recvData();
-    else if (groupB.containsMyRank())
-    dec.sendData();
-    ...
-    \endcode
-
-    Creating a ParaFIELD to be attached to the %DEC is done in exactly the same way as for
-    the other DECs, if only the partitioning of the support mesh differs.
-    In the case where the
-    fields have also different *component* topologies, creating the ParaFIELD
-    requires some more effort. See the \ref para-over "parallelism" section for more details.
-  */
-
-
-  StructuredCoincidentDEC::StructuredCoincidentDEC():_topo_source(0),_topo_target(0),
-                                                     _send_counts(0),_recv_counts(0),
-                                                     _send_displs(0),_recv_displs(0),
-                                                     _recv_buffer(0),_send_buffer(0)
+  StructuredCoincidentDEC::StructuredCoincidentDEC():_topo_source(nullptr),_topo_target(nullptr),
+                                                     _owns_topo_source(false), _owns_topo_target(false),
+                                                     _send_counts(nullptr),_recv_counts(nullptr),
+                                                     _send_displs(nullptr),_recv_displs(nullptr),
+                                                     _recv_buffer(nullptr),_send_buffer(nullptr)
   {
   }
 
+  StructuredCoincidentDEC::StructuredCoincidentDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group):
+      DisjointDEC(local_group,distant_group),
+      _topo_source(nullptr),_topo_target(nullptr),
+      _owns_topo_source(false), _owns_topo_target(false),
+      _send_counts(nullptr),_recv_counts(nullptr),
+      _send_displs(nullptr),_recv_displs(nullptr),
+      _recv_buffer(nullptr),_send_buffer(nullptr)
+  {
+  }
 
   StructuredCoincidentDEC::~StructuredCoincidentDEC()
+  {
+    release();
+  }
+
+  /** Destructor involves MPI operations: make sure this is accessible from a proper
+   * method for Python wrapping.
+   */
+  void StructuredCoincidentDEC::release()
   {
     delete [] _send_buffer;
     delete [] _recv_buffer;
-    delete []_send_displs;
+    delete [] _send_displs;
     delete [] _recv_displs;
     delete [] _send_counts;
     delete [] _recv_counts;
-    if (! _source_group->containsMyRank())
+    _send_buffer = nullptr;
+    _recv_buffer = nullptr;
+    _send_displs = nullptr;
+    _recv_displs = nullptr;
+    _send_counts = nullptr;
+    _recv_counts = nullptr;
+
+    if (_owns_topo_source)
       delete _topo_source;
-    if(!_target_group->containsMyRank())
+    if (_owns_topo_target)
       delete _topo_target;
-  }
+    _topo_source = nullptr;
+    _topo_target = nullptr;
+    _owns_topo_source = false;
+    _owns_topo_target = false;
 
-  StructuredCoincidentDEC::StructuredCoincidentDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group):
-      DisjointDEC(local_group,distant_group),
-      _topo_source(0),_topo_target(0),
-      _send_counts(0),_recv_counts(0),
-      _send_displs(0),_recv_displs(0),
-      _recv_buffer(0),_send_buffer(0)
-  {
+    DisjointDEC::cleanInstance();
   }
 
   /*! Synchronization process for exchanging topologies
@@ -125,16 +93,22 @@ namespace MEDCoupling
   {
     if (_source_group->containsMyRank())
       _topo_source = dynamic_cast<BlockTopology*>(_local_field->getTopology());
+    else
+      _owns_topo_source = true;  // _topo_source will be filled by broadcastTopology below
     if (_target_group->containsMyRank())
       _topo_target = dynamic_cast<BlockTopology*>(_local_field->getTopology());
+    else
+      _owns_topo_target = true;  // _topo_target will be filled by broadcastTopology below
 
     // Transmitting source topology to target code
+    MESSAGE ("Broadcast source topo ...");
     broadcastTopology(_topo_source,1000);
+
     // Transmitting target topology to source code
+    MESSAGE ("Broadcast target topo ...");
     broadcastTopology(_topo_target,2000);
     if (_topo_source->getNbElements() != _topo_target->getNbElements())
       throw INTERP_KERNEL::Exception("Incompatible dimensions for target and source topologies");
-
   }
 
   /*! Creates the arrays necessary for the data transfer
@@ -283,8 +257,7 @@ namespace MEDCoupling
 
     MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface);
 
-    // The master proc creates a send buffer containing
-    // a serialized topology
+    // The master proc creates a send buffer containing a serialized topology
     int rank_master;
 
     if (topo!=0 && topo->getProcGroup()->myRank()==0)
@@ -304,7 +277,7 @@ namespace MEDCoupling
       {
         MESSAGE(" rank "<<group->myRank()<< " waiting ...");
         _comm_interface->recv(&rank_master, 1,MPI_INT, MPI_ANY_SOURCE, tag+group->myRank(), *(group->getComm()),&status);
-        MESSAGE(" rank "<<group->myRank()<< "received master rank"<<rank_master);
+        MESSAGE(" rank "<<group->myRank()<< " received master rank "<<rank_master);
       }
     // The topology is broadcasted to all processors in the group
     _comm_interface->broadcast(&size, 1,MPI_ID_TYPE,rank_master,*(group->getComm()));
@@ -314,9 +287,7 @@ namespace MEDCoupling
       copy(serializer, serializer+size, buffer);
     _comm_interface->broadcast(buffer,(int)size,MPI_ID_TYPE,rank_master,*(group->getComm()));
 
-    // Processors which did not possess the source topology
-    // unserialize it
-
+    // Processors which did not possess the source topology unserialize it
     BlockTopology* topotemp=new BlockTopology();
     topotemp->unserialize(buffer, *_comm_interface);
 
@@ -414,5 +385,6 @@ namespace MEDCoupling
         synchronizeTopology();
         prepareTargetDE();
       }
+    MESSAGE ("sync OK");
   }
 }