From: Anthony Geay Date: Mon, 27 Apr 2020 21:39:40 +0000 (+0200) Subject: Still some imp into ParaUMesh X-Git-Tag: V9_5_0b1~8 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f4059c6250ce5138a3347ecedc4df3fdc4d7f8e0;p=tools%2Fmedcoupling.git Still some imp into ParaUMesh --- diff --git a/src/ParaMEDMEM/ParaUMesh.cxx b/src/ParaMEDMEM/ParaUMesh.cxx index 60d44a323..7e3060892 100644 --- a/src/ParaMEDMEM/ParaUMesh.cxx +++ b/src/ParaMEDMEM/ParaUMesh.cxx @@ -131,6 +131,85 @@ MCAuto ParaUMesh::getCellIdsLyingOnNodes(const DataArrayIdType return cellIdsFromProcs; } +DataArrayIdType *ParaUMesh::redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const +{ + MPI_Comm comm(MPI_COMM_WORLD); + CommInterface ci; + std::unique_ptr allGlobalCellIds,allGlobalCellIdsIndex; + int size(ci.allGatherArrays(comm,globalCellIds,allGlobalCellIds,allGlobalCellIdsIndex)); + // Prepare ParaUMesh parts to be sent : compute for each proc the contribution of current rank. + std::vector< MCAuto > globalCellIdsToBeSent(size); + std::vector< MCAuto > fieldToBeSent(size); + for(int curRk = 0 ; curRk < size ; ++curRk) + { + mcIdType offset(allGlobalCellIdsIndex[curRk]); + MCAuto globalCellIdsOfCurProc(DataArrayIdType::New()); + globalCellIdsOfCurProc->useArray(allGlobalCellIds.get()+offset,false,DeallocType::CPP_DEALLOC,allGlobalCellIdsIndex[curRk+1]-offset,1); + // the key call is here : compute for rank curRk the cells to be sent + MCAuto globalCellIdsCaptured(_cell_global->buildIntersection(globalCellIdsOfCurProc));// OK for the global cellIds + MCAuto localCellIdsCaptured(_cell_global->findIdForEach(globalCellIdsCaptured->begin(),globalCellIdsCaptured->end())); + globalCellIdsToBeSent[curRk] = globalCellIdsCaptured; + fieldToBeSent[curRk] = fieldValueToRed->selectByTupleIdSafe(localCellIdsCaptured->begin(),localCellIdsCaptured->end()); + } + // Receive + std::vector< MCAuto > globalCellIdsReceived; + ci.allToAllArrays(comm,globalCellIdsToBeSent,globalCellIdsReceived); + std::vector< MCAuto > fieldValueReceived; + ci.allToAllArrays(comm,fieldToBeSent,fieldValueReceived); + // use globalCellIdsReceived to reorganize everything + MCAuto aggregatedCellIds( DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(globalCellIdsReceived)) ); + MCAuto aggregatedCellIdsSorted(aggregatedCellIds->copySorted()); + MCAuto idsIntoAggregatedIds(DataArrayIdType::FindPermutationFromFirstToSecondDuplicate(aggregatedCellIdsSorted,aggregatedCellIds)); + MCAuto cellIdsOfSameNodeIds(aggregatedCellIdsSorted->indexOfSameConsecutiveValueGroups()); + MCAuto n2o_cells(idsIntoAggregatedIds->selectByTupleIdSafe(cellIdsOfSameNodeIds->begin(),cellIdsOfSameNodeIds->end()-1));//new == new ordering so that global cell ids are sorted . old == coarse ordering implied by the aggregation + // + MCAuto fieldAggregated(DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(fieldValueReceived))); + MCAuto ret(fieldAggregated->selectByTupleIdSafe(n2o_cells->begin(),n2o_cells->end())); + return ret.retn(); +} + +DataArrayIdType *ParaUMesh::redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const +{ + MPI_Comm comm(MPI_COMM_WORLD); + CommInterface ci; + std::unique_ptr allGlobalCellIds,allGlobalCellIdsIndex; + int size(ci.allGatherArrays(comm,globalCellIds,allGlobalCellIds,allGlobalCellIdsIndex)); + // Prepare ParaUMesh parts to be sent : compute for each proc the contribution of current rank. + std::vector< MCAuto > globalNodeIdsToBeSent(size); + std::vector< MCAuto > fieldToBeSent(size); + for(int curRk = 0 ; curRk < size ; ++curRk) + { + mcIdType offset(allGlobalCellIdsIndex[curRk]); + MCAuto globalCellIdsOfCurProc(DataArrayIdType::New()); + globalCellIdsOfCurProc->useArray(allGlobalCellIds.get()+offset,false,DeallocType::CPP_DEALLOC,allGlobalCellIdsIndex[curRk+1]-offset,1); + // the key call is here : compute for rank curRk the cells to be sent + MCAuto globalCellIdsCaptured(_cell_global->buildIntersection(globalCellIdsOfCurProc));// OK for the global cellIds + MCAuto localCellIdsCaptured(_cell_global->findIdForEach(globalCellIdsCaptured->begin(),globalCellIdsCaptured->end())); + MCAuto meshPart(_mesh->buildPartOfMySelf(localCellIdsCaptured->begin(),localCellIdsCaptured->end(),true)); + MCAuto o2n(meshPart->zipCoordsTraducer());// OK for the mesh + MCAuto n2o(o2n->invertArrayO2N2N2O(meshPart->getNumberOfNodes())); + MCAuto globalNodeIdsPart(_node_global->selectByTupleIdSafe(n2o->begin(),n2o->end())); // OK for the global nodeIds + globalNodeIdsToBeSent[curRk] = globalNodeIdsPart; + fieldToBeSent[curRk] = fieldValueToRed->selectByTupleIdSafe(n2o->begin(),n2o->end()); + } + // Receive + std::vector< MCAuto > globalNodeIdsReceived; + ci.allToAllArrays(comm,globalNodeIdsToBeSent,globalNodeIdsReceived); + std::vector< MCAuto > fieldValueReceived; + ci.allToAllArrays(comm,fieldToBeSent,fieldValueReceived); + // firstly deal with nodes. + MCAuto aggregatedNodeIds( DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(globalNodeIdsReceived)) ); + MCAuto aggregatedNodeIdsSorted(aggregatedNodeIds->copySorted()); + MCAuto nodeIdsIntoAggregatedIds(DataArrayIdType::FindPermutationFromFirstToSecondDuplicate(aggregatedNodeIdsSorted,aggregatedNodeIds)); + MCAuto idxOfSameNodeIds(aggregatedNodeIdsSorted->indexOfSameConsecutiveValueGroups()); + MCAuto n2o_nodes(nodeIdsIntoAggregatedIds->selectByTupleIdSafe(idxOfSameNodeIds->begin(),idxOfSameNodeIds->end()-1));//new == new ordering so that global node ids are sorted . old == coarse ordering implied by the aggregation + // + MCAuto fieldAggregated(DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(fieldValueReceived))); + MCAuto ret(fieldAggregated->selectByTupleIdSafe(n2o_nodes->begin(),n2o_nodes->end())); + // + return ret.retn(); +} + /*! * Return part of \a this mesh split over COMM_WORLD. Part is defined by global cell ids array \a globaCellIds. */ diff --git a/src/ParaMEDMEM/ParaUMesh.hxx b/src/ParaMEDMEM/ParaUMesh.hxx index 5247b3716..d8a938718 100644 --- a/src/ParaMEDMEM/ParaUMesh.hxx +++ b/src/ParaMEDMEM/ParaUMesh.hxx @@ -40,6 +40,8 @@ namespace MEDCoupling static ParaUMesh *New(MEDCouplingUMesh *mesh, DataArrayIdType *globalCellIds, DataArrayIdType *globalNodeIds); MCAuto getCellIdsLyingOnNodes(const DataArrayIdType *globalNodeIds, bool fullyIn) const; ParaUMesh *redistributeCells(const DataArrayIdType *globalCellIds) const; + DataArrayIdType *redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const; + DataArrayIdType *redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const; MEDCouplingUMesh *getMesh() { return _mesh; } DataArrayIdType *getGlobalCellIds() { return _cell_global; } DataArrayIdType *getGlobalNodeIds() { return _node_global; } diff --git a/src/ParaMEDMEM_Swig/ParaMEDMEMCommon.i b/src/ParaMEDMEM_Swig/ParaMEDMEMCommon.i index b1fcf0103..4c1ff6dae 100644 --- a/src/ParaMEDMEM_Swig/ParaMEDMEMCommon.i +++ b/src/ParaMEDMEM_Swig/ParaMEDMEMCommon.i @@ -64,6 +64,8 @@ using namespace ICoCo; %newobject MEDCoupling::ParaUMesh::getGlobalNodeIds; %newobject MEDCoupling::ParaUMesh::getCellIdsLyingOnNodes; %newobject MEDCoupling::ParaUMesh::redistributeCells; +%newobject MEDCoupling::ParaUMesh::redistributeCellField; +%newobject MEDCoupling::ParaUMesh::redistributeNodeField; %newobject MEDCoupling::ParaSkyLineArray::New; %newobject MEDCoupling::ParaSkyLineArray::equiRedistribute; %newobject MEDCoupling::ParaSkyLineArray::getSkyLineArray; @@ -160,6 +162,8 @@ namespace MEDCoupling public: static ParaUMesh *New(MEDCouplingUMesh *mesh, DataArrayIdType *globalCellIds, DataArrayIdType *globalNodeIds); ParaUMesh *redistributeCells(const DataArrayIdType *globalCellIds) const; + DataArrayIdType *redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const; + DataArrayIdType *redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const; %extend { ParaUMesh(MEDCouplingUMesh *mesh, DataArrayIdType *globalCellIds, DataArrayIdType *globalNodeIds)