X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDPartitioner%2FMEDPARTITIONER_ParallelTopology.cxx;h=b4a415bf26b692b2a5207d27c2edc080c87e0202;hb=f970a374f8228afe51c80cff4df9399ee6638477;hp=a97f22089d2232e823a12907ee01637d310499ab;hpb=10f37bf6f33a762626d7f1093b2f5450c1688667;p=tools%2Fmedcoupling.git diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx index a97f22089..b4a415bf2 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2022 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 // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,19 +20,22 @@ #include "MEDPARTITIONER_MeshCollection.hxx" #include "MEDPARTITIONER_Topology.hxx" #include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" #include "MEDPARTITIONER_ParallelTopology.hxx" #include "MEDPARTITIONER_ConnectZone.hxx" #include "MEDPARTITIONER_Utils.hxx" +#include "MEDCouplingSkyLineArray.hxx" #include "MEDCouplingUMesh.hxx" #include "InterpKernelHashMap.hxx" +#include "MCIdType.hxx" #include #include #include #include -#ifdef HAVE_MPI2 +#ifdef HAVE_MPI #include #endif @@ -43,9 +46,9 @@ ParallelTopology::ParallelTopology():_nb_domain(0),_mesh_dimension(0) } //constructing topology according to mesh collection without global numerotation (use setGlobalNumerotation later) -ParallelTopology::ParallelTopology(const std::vector& meshes) +ParallelTopology::ParallelTopology(const std::vector& meshes) { - _nb_domain=meshes.size(); + _nb_domain=(int)meshes.size(); _nb_cells.resize(_nb_domain); _nb_nodes.resize(_nb_domain); // _nb_faces.resize(_nb_domain); @@ -61,7 +64,7 @@ ParallelTopology::ParallelTopology(const std::vector20 && !parallel_mode) - std::cout << "WARNING : ParallelTopology contructor without parallel_mode" << std::endl; + std::cout << "WARNING : ParallelTopology constructor without parallel_mode" << std::endl; for (int idomain=0; idomain<_nb_domain; idomain++) { if ( !meshes[idomain] ) continue; @@ -96,17 +99,17 @@ void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSe for (int idomain=0; idomain<_nb_domain; idomain++) { _loc_to_glob[idomain].resize(_nb_cells[idomain]); - int domainCellShift=domainSelector->getDomainCellShift(idomain); - for (int i=0; i<_nb_cells[idomain]; i++) + mcIdType domainCellShift=domainSelector->getDomainCellShift(idomain); + for (mcIdType i=0; i<_nb_cells[idomain]; i++) { - int global=domainCellShift+i ; + mcIdType global=domainCellShift+i ; _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); _loc_to_glob[idomain][i]=global; if (MyGlobals::_Verbose>500) std::cout << "c" << idomain << "|" << i << "|" << global << " "; } } -#ifdef HAVE_MPI2 +#ifdef HAVE_MPI if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace #endif if (MyGlobals::_Is0verbose>500) std::cout << std::endl; @@ -115,17 +118,17 @@ void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSe for (int idomain=0; idomain<_nb_domain; idomain++) { _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]); - int domainNodeShift=domainSelector->getDomainNodeShift(idomain); - for (int i=0; i<_nb_nodes[idomain]; i++) + mcIdType domainNodeShift=domainSelector->getDomainNodeShift(idomain); + for (mcIdType i=0; i<_nb_nodes[idomain]; i++) { - int global=domainNodeShift+i ; + mcIdType global=domainNodeShift+i ; _node_glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); _node_loc_to_glob[idomain][i]=global; if (MyGlobals::_Verbose>500) std::cout << "n" << idomain << "|" << i << "|" << global << " "; } } -#ifdef HAVE_MPI2 +#ifdef HAVE_MPI if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace #endif if (MyGlobals::_Is0verbose>500) std::cout << std::endl; @@ -138,16 +141,16 @@ void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSe } //constructing topology according to mesh collection -ParallelTopology::ParallelTopology(const std::vector& meshes, +ParallelTopology::ParallelTopology(const std::vector& meshes, const std::vector& cz, - std::vector& cellglobal, - std::vector& nodeglobal, - std::vector& faceglobal) + std::vector& cellglobal, + std::vector& nodeglobal, + std::vector& faceglobal) { - _nb_domain=meshes.size(); - int index_global=0; - int index_node_global=0; - int index_face_global=0; + _nb_domain=(int)meshes.size(); + mcIdType index_global=0; + mcIdType index_node_global=0; + mcIdType index_face_global=0; _nb_cells.resize(_nb_domain); _nb_nodes.resize(_nb_domain); @@ -175,9 +178,9 @@ ParallelTopology::ParallelTopology(const std::vectorgetNumberOfNodes()); - for (int i=0; igetNumberOfNodes(); i++) + for (mcIdType i=0; igetNumberOfNodes(); i++) { _node_glob_to_loc.insert(std::make_pair(i,std::make_pair(0,i))); _node_loc_to_glob[0][i]=i; @@ -214,20 +217,20 @@ ParallelTopology::ParallelTopology(const std::vectorgetNumberOfNodes(); - INTERP_KERNEL::HashMap > local2distant; + INTERP_KERNEL::HashMap > local2distant; _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]); for (std::size_t icz=0; iczgetLocalDomainNumber() == idomain && cz[icz]->getLocalDomainNumber()>cz[icz]->getDistantDomainNumber()) { - int nb_node= cz[icz]->getNodeNumber(); - const int* node_corresp=cz[icz]->getNodeCorrespValue(); + mcIdType nb_node= cz[icz]->getNodeNumber(); + const mcIdType* node_corresp=cz[icz]->getNodeCorrespValue(); int distant_ip = cz[icz]->getDistantDomainNumber(); - for (int i=0; i< nb_node; i++) + for (mcIdType i=0; i< nb_node; i++) { - int local= node_corresp[i*2]; - int distant = node_corresp[i*2+1]; + mcIdType local= node_corresp[i*2]; + mcIdType distant = node_corresp[i*2+1]; local2distant.insert(std::make_pair(local, std::make_pair(distant_ip,distant))); } } @@ -235,7 +238,7 @@ ParallelTopology::ParallelTopology(const std::vectorsecond).first; - int distant = (local2distant.find(inode)->second).second; - int global_number=_loc_to_glob[ip][distant]; + mcIdType distant = (local2distant.find(inode)->second).second; + mcIdType global_number=_loc_to_glob[ip][distant]; _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode))); _node_loc_to_glob[idomain][inode]=global_number; } @@ -257,9 +260,9 @@ ParallelTopology::ParallelTopology(const std::vector200) std::cout << "proc " << MyGlobals::_Rank << " : new topology oldNbDomain " << oldTopology->nbDomain() << " newNbDomain " << _nb_domain << std::endl; @@ -290,7 +293,7 @@ ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_d _node_loc_to_glob.resize(_nb_domain); _face_loc_to_glob.resize(_nb_domain); - const int* part=graph->getPart(); //all cells for this proc (may be more domains) + const mcIdType* part=graph->getPart(); //all cells for this proc (may be more domains) _nb_total_cells=graph->nbVertices(); //all cells for this proc (may be more domains) if (MyGlobals::_Verbose>300) std::cout << "proc " << MyGlobals::_Rank << " : topology from partition, nbTotalCells " << _nb_total_cells << std::endl; @@ -298,17 +301,17 @@ ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_d int icellProc=0; //all cells of my domains are concatenated in part for (int iold=0; ioldnbDomain(); iold++) { - int ioldNbCell=oldTopology->getCellNumber(iold); + mcIdType ioldNbCell=oldTopology->getCellNumber(iold); //std::cout<<"proc "< globalids(ioldNbCell); + std::vector globalids(ioldNbCell); oldTopology->getCellList(iold, &globalids[0]); //unique global numerotation - for (int icell=0; icell(part[icellProc]); _nb_cells[idomain]++; icellProc++; - int iGlobalCell=globalids[icell]; + mcIdType iGlobalCell=globalids[icell]; _loc_to_glob[idomain].push_back(iGlobalCell); _glob_to_loc.insert(std::make_pair(iGlobalCell, std::make_pair(idomain, _nb_cells[idomain]))); } @@ -316,26 +319,83 @@ ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_d if (MyGlobals::_Verbose>300) for (int idomain=0; idomain<_nb_domain; idomain++) - std::cout << "proc " << MyGlobals::_Rank << " : nbCells in new domain " << idomain << " : " << _nb_cells[idomain] << std::endl; + std::cout << "proc " << MyGlobals::_Rank << " : nbCells in new domain " << idomain << " : " << _nb_cells[idomain] << std::endl; + + // JOINTs + + if ( MyGlobals::_Create_Joints && nb_domain > 1 ) + { + std::vector< std::vector< std::vector< mcIdType > > > cellCorresp( nb_domain ); + for ( int idomain = 0; idomain < nb_domain; ++idomain ) + { + cellCorresp[ idomain ].resize( nb_domain ); + } + const MEDCoupling::MEDCouplingSkyLineArray* skylinegraph = graph->getGraph(); + const mcIdType* index = skylinegraph->getIndex(); + const mcIdType* value = skylinegraph->getValues(); + const mcIdType nbCells = skylinegraph->getNumberOf(); + + for ( mcIdType iGlob = 0; iGlob < nbCells; ++iGlob ) + { + int iGlobDom = FromIdType(part[ iGlob ]); + for ( mcIdType i = index[ iGlob ]; i < index[ iGlob+1 ]; i++ ) + { + mcIdType iGlobNear = value[ i ]; + if ( iGlob > iGlobNear ) + continue; // treat ( iGlob, iGlobNear ) pair once + int iGlobNearDom = FromIdType(part[ iGlobNear ]); + if ( iGlobDom != iGlobNearDom ) + { + mcIdType iLoc = convertGlobalCell( iGlob ).second - 1; // to MEDCoupling fmt + mcIdType iLocNear = convertGlobalCell( iGlobNear ).second - 1; + cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLoc ); + cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLocNear ); + cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLocNear ); + cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLoc ); + } + } + } + for ( int idomain = 0; idomain < nb_domain; ++idomain ) + { + for ( int idomainNear = 0; idomainNear < nb_domain; ++idomainNear ) + { + std::vector< mcIdType > & corresp = cellCorresp[ idomain ][ idomainNear ]; + if ( corresp.empty() ) + continue; + MEDPARTITIONER::ConnectZone* cz = new MEDPARTITIONER::ConnectZone(); + cz->setName( "Connect Zone defined by MEDPARTITIONER" ); + cz->setDistantDomainNumber( idomainNear ); + cz->setLocalDomainNumber ( idomain ); + cz->setEntityCorresp( 0,0, &corresp[0], ToIdType( corresp.size()/2 )); + _connect_zones.push_back( cz ); + } + } + } } ParallelTopology::~ParallelTopology() { -} + for ( size_t i = 0; i < _connect_zones.size(); ++i ) + { + delete _connect_zones[i]; + _connect_zones[i] = 0; + } + _connect_zones.clear(); +} /*!Converts a list of global node numbers * to a distributed array with local cell numbers. - * + * * If a node in the list is represented on several domains, * only the first value is returned * */ -void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int* ip) +void ParallelTopology::convertGlobalNodeList(const mcIdType* node_list, mcIdType nbnode, mcIdType* local, int* ip) { - if (_node_glob_to_loc.empty()) + if (_node_glob_to_loc.empty()) throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); - for (int i=0; i< nbnode; i++) + for (mcIdType i=0; i< nbnode; i++) { - std::pair local_node = _node_glob_to_loc.find(node_list[i])->second; + std::pair local_node = _node_glob_to_loc.find(node_list[i])->second; ip[i]=local_node.first; local[i]=local_node.second; } @@ -348,14 +408,14 @@ void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, i * only the value with domain ip is returned * * */ -void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int ip) +void ParallelTopology::convertGlobalNodeList(const mcIdType* node_list, mcIdType nbnode, mcIdType* local, int ip) { if (_node_glob_to_loc.empty()) throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); - for (int i=0; i< nbnode; i++) + for (mcIdType i=0; i< nbnode; i++) { - typedef INTERP_KERNEL::HashMultiMap >::iterator mmiter; + typedef INTERP_KERNEL::HashMultiMap >::iterator mmiter; std::pair range=_node_glob_to_loc.equal_range(node_list[i]); for (mmiter it=range.first; it !=range.second; it++) { @@ -372,24 +432,24 @@ void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, i * If a node in the list is represented on several domains, * all the values are put in the array * */ -void ParallelTopology::convertGlobalNodeListWithTwins(const int* node_list, int nbnode, int*& local, int*& ip,int*& full_array, int& size) +void ParallelTopology::convertGlobalNodeListWithTwins(const mcIdType* node_list, mcIdType nbnode, mcIdType*& local, int*& ip,mcIdType*& full_array, mcIdType& size) { if (_node_glob_to_loc.empty()) throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); size=0; - for (int i=0; i< nbnode; i++) + for (mcIdType i=0; i< nbnode; i++) { - int count= _node_glob_to_loc.count(node_list[i]); + mcIdType count= ToIdType( _node_glob_to_loc.count(node_list[i])); size+=count; } - int index=0; + mcIdType index=0; ip=new int[size]; - local=new int[size]; - full_array=new int[size]; - for (int i=0; i< nbnode; i++) + local=new mcIdType[size]; + full_array=new mcIdType[size]; + for (mcIdType i=0; i< nbnode; i++) { - typedef INTERP_KERNEL::HashMultiMap >::iterator mmiter; + typedef INTERP_KERNEL::HashMultiMap >::iterator mmiter; std::pair range=_node_glob_to_loc.equal_range(node_list[i]); for (mmiter it=range.first; it !=range.second; it++) { @@ -408,22 +468,22 @@ void ParallelTopology::convertGlobalNodeListWithTwins(const int* node_list, int * If a face in the list is represented on several domains, * all the values are put in the array * */ -void ParallelTopology::convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size) +void ParallelTopology::convertGlobalFaceListWithTwins(const mcIdType* face_list, mcIdType nbface, mcIdType*& local, int*& ip, mcIdType*& full_array,mcIdType& size) { size=0; - for (int i=0; i< nbface; i++) + for (mcIdType i=0; i< nbface; i++) { //int count = _face_glob_to_loc.count(face_list[i]); //if (count >1) MESSAGE_MED("face en doublon "< >::iterator mmiter; + typedef INTERP_KERNEL::HashMultiMap >::iterator mmiter; std::pair range=_face_glob_to_loc.equal_range(face_list[i]); for (mmiter it=range.first; it !=range.second; it++) { @@ -438,11 +498,11 @@ void ParallelTopology::convertGlobalFaceListWithTwins(const int* face_list, int //!converts a list of global cell numbers //!to a distributed array with local cell numbers -void ParallelTopology::convertGlobalCellList(const int* cell_list, int nbcell, int* local, int* ip) +void ParallelTopology::convertGlobalCellList(const mcIdType* cell_list, mcIdType nbcell, mcIdType* local, int* ip) { - for (int i=0; i >::const_iterator iter = _glob_to_loc.find(cell_list[i]); + INTERP_KERNEL::HashMap >::const_iterator iter = _glob_to_loc.find(cell_list[i]); if (iter == _glob_to_loc.end()) { std::cerr << "proc " << MyGlobals::_Rank << " : KO cell_list[" << i << "] : " << cell_list[i] << std::endl; @@ -459,11 +519,11 @@ void ParallelTopology::convertGlobalCellList(const int* cell_list, int nbcell, i /*!Converts a list of global face numbers * to a distributed array with local face numbers */ -void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int* ip) +void ParallelTopology::convertGlobalFaceList(const mcIdType* face_list, mcIdType nbface, mcIdType* local, int* ip) { - for (int i=0; i< nbface; i++) + for (mcIdType i=0; i< nbface; i++) { - INTERP_KERNEL::HashMap >::const_iterator iter = _face_glob_to_loc.find(face_list[i]); + INTERP_KERNEL::HashMap >::const_iterator iter = _face_glob_to_loc.find(face_list[i]); if (iter == _face_glob_to_loc.end()) { throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalFaceList : Face not found"); @@ -480,11 +540,11 @@ void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, i * only the value with domain ip is returned * */ -void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int ip) +void ParallelTopology::convertGlobalFaceList(const mcIdType* face_list, mcIdType nbface, mcIdType* local, int ip) { - for (int i=0; i< nbface; i++) + for (mcIdType i=0; i< nbface; i++) { - typedef INTERP_KERNEL::HashMultiMap >::iterator mmiter; + typedef INTERP_KERNEL::HashMultiMap >::iterator mmiter; std::pair range=_face_glob_to_loc.equal_range(face_list[i]); for (mmiter it=range.first; it !=range.second; it++) { @@ -499,13 +559,13 @@ void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, i //replacing a table of global numbering with a table with local numberings // type_connectivity contains global connectivity for each type in input // type_connectivity contains local connectivity for each type in output -void ParallelTopology::convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain) +void ParallelTopology::convertToLocal2ndVersion(mcIdType* nodes, mcIdType nbnodes, int idomain) { - for (int inode=0; inode