X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FParaMEDMEM%2FDisjointDEC.cxx;h=4db440a6b72c22015e3a616000bbf5dd9f182afe;hb=7e632de173a3f7701ed288471c5de2bc0f55dbc3;hp=b2ba8f79555b10204eea93b98dbc3864ea76e1f6;hpb=c9020954af7fe85dd75b34e5ea7951b0f1f4cb25;p=tools%2Fmedcoupling.git diff --git a/src/ParaMEDMEM/DisjointDEC.cxx b/src/ParaMEDMEM/DisjointDEC.cxx index b2ba8f795..4db440a6b 100644 --- a/src/ParaMEDMEM/DisjointDEC.cxx +++ b/src/ParaMEDMEM/DisjointDEC.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -32,7 +32,7 @@ #include -namespace ParaMEDMEM +namespace MEDCoupling { /*! @@ -43,14 +43,14 @@ namespace ParaMEDMEM * * Abstract interface class representing a link between two * processor groups for exchanging mesh or field data. The two processor groups must - * have a void intersection (\ref ParaMEDMEM::OverlapDEC "OverlapDEC" is to be considered otherwise). + * have a void intersection (\ref MEDCoupling::OverlapDEC "OverlapDEC" is to be considered otherwise). * The %DEC is initialized by attaching a field on the receiving or on the * sending side. * * The data is sent or received through calls to the (abstract) methods recvData() and sendData(). * - * One can attach either a \c ParaMEDMEM::ParaFIELD, or a - * \c ICoCo::Field, or directly a \c ParaMEDMEM::MEDCouplingFieldDouble instance. + * One can attach either a \c MEDCoupling::ParaFIELD, or a + * \c ICoCo::Field, or directly a \c MEDCoupling::MEDCouplingFieldDouble instance. * See the various signatures of the method DisjointDEC::attachLocalField() * * The derivations of this class should be considered for practical instanciation: @@ -60,7 +60,7 @@ namespace ParaMEDMEM * * \section DisjointDEC-options DisjointDEC options * The options supported by %DisjointDEC objects are the same that the ones supported for all - * DECs in general and are all inherited from the class \ref ParaMEDMEM::DECOptions "DECOptions" + * DECs in general and are all inherited from the class \ref MEDCoupling::DECOptions "DECOptions" * */ @@ -73,6 +73,7 @@ namespace ParaMEDMEM _owns_groups(false), _union_comm(MPI_COMM_NULL) { + checkPartitionGroup(); _union_group = source_group.fuse(target_group); } @@ -101,16 +102,29 @@ namespace ParaMEDMEM void DisjointDEC::copyInstance(const DisjointDEC& other) { DEC::copyFrom(other); - if(other._target_group) + if (other._union_comm != MPI_COMM_NULL) { - _target_group=other._target_group->deepCpy(); - _owns_groups=true; - } - if(other._source_group) - { - _source_group=other._source_group->deepCpy(); - _owns_groups=true; + // Tricky: the DEC is responsible for the management of _union_comm. And this comm is referenced by + // the MPIProcGroups (source/targets). In the case where _union_comm is not NULL we must take care of rebuilding the + // MPIProcGroups with a communicator that will survive the destruction of 'other'. + _owns_groups = true; + MPI_Comm_dup(other._union_comm, &_union_comm); +// std::cout << "DUP union comm - new is "<< _union_comm << "\n"; + _target_group = new MPIProcessorGroup(*_comm_interface, other._target_group->getProcIDs(), _union_comm); + _source_group = new MPIProcessorGroup(*_comm_interface, other._source_group->getProcIDs(), _union_comm); } + else{ + if(other._target_group) + { + _target_group=other._target_group->deepCopy(); + _owns_groups=true; + } + if(other._source_group) + { + _source_group=other._source_group->deepCopy(); + _owns_groups=true; + } + } if (_source_group && _target_group) _union_group = _source_group->fuse(*_target_group); } @@ -124,7 +138,7 @@ namespace ParaMEDMEM _comm_interface(0), _union_comm(MPI_COMM_NULL) { - ParaMEDMEM::CommInterface comm; + MEDCoupling::CommInterface comm; // Create the list of procs including source and target std::set union_ids; // source and target ids in world_comm union_ids.insert(source_ids.begin(),source_ids.end()); @@ -205,6 +219,28 @@ namespace ParaMEDMEM _comm_interface->commFree(&_union_comm); } + /** + * Check that the sources and targets procs form a partition of the world communicator referenced in the groups. + * This world communicator is not necessarily MPI_WORLD_COMM, but it has to be covered completly for the DECs to work. + */ + void DisjointDEC::checkPartitionGroup() const + { + int size = -1; + MPIProcessorGroup * tgt = static_cast(_target_group); + MPIProcessorGroup * src = static_cast(_source_group); + MPI_Comm comm_t = tgt->getWorldComm(); + MPI_Comm comm_s = src->getWorldComm(); + if (comm_t != comm_s) + throw INTERP_KERNEL::Exception("DisjointDEC constructor: Inconsistent world communicator when building DisjointDEC"); + MPI_Comm_size(comm_t, &size); + + std::set union_ids; // source and target ids in world_comm + union_ids.insert(src->getProcIDs().begin(),src->getProcIDs().end()); + union_ids.insert(tgt->getProcIDs().begin(),tgt->getProcIDs().end()); + if(union_ids.size()!=size) + throw INTERP_KERNEL::Exception("DisjointDEC constructor: source_ids and target_ids do not form a partition of the communicator! Restrain the world communicator passed to MPIProcessorGroup ctor."); + } + void DisjointDEC::setNature(NatureOfField nature) { if(_local_field)