From: abn Date: Thu, 7 Oct 2021 19:17:03 +0000 (+0200) Subject: WIP working version. Franck to test ... X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=9d648cda2a202093e04aaa308d05f62879db088d;p=tools%2Fmedcoupling.git WIP working version. Franck to test ... --- diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index b31bb1634..3a63bc6d6 100755 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -2360,13 +2360,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const * * \param [in] otherDimM1OnSameCoords a mesh lying on the same coords than \b this and with a mesh dimension equal to those of \b this minus 1. WARNING this input * parameter is altered during the call. - * \param [out] nodeIdsToDuplicate node ids needed to be duplicated following the algorithm explain above. - * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed. - * \param [out] cellIdsNotModified cell ids in \b this that lies on \b otherDimM1OnSameCoords mesh whose connectivity do \b not need to be modified as it is the case for \b cellIdsNeededToBeRenum. + * \return node ids which need to be duplicated following the algorithm explained above. * */ -void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayIdType *& nodeIdsToDuplicate, - DataArrayIdType *& cellIdsNeededToBeRenum, DataArrayIdType *& cellIdsNotModified) const +DataArrayIdType* MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords) const { using DAInt = MCAuto; using MCUMesh = MCAuto; @@ -2395,7 +2392,7 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On // Remove from the list points on the boundary of the M0 mesh (those need duplication!) dt0=DataArrayIdType::New(),dit0=DataArrayIdType::New(),rdt0=DataArrayIdType::New(),rdit0=DataArrayIdType::New(); MCUMesh m0desc = buildDescendingConnectivity(dt0, dit0, rdt0, rdit0); dt0=0; dit0=0; rdt0=0; - dsi = rdit0->deltaShiftIndex(); + dsi = rdit0->deltaShiftIndex(); rdit0=0; DAInt boundSegs = dsi->findIdsEqual(1); dsi = 0; // boundary segs/faces of the M0 mesh MCUMesh m0descSkin = static_cast(m0desc->buildPartOfMySelf(boundSegs->begin(),boundSegs->end(), true)); DAInt fNodes = m0descSkin->computeFetchedNodeIds(); @@ -2423,98 +2420,230 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On DAInt notDuplSkin = m1IntersecSkin->findBoundaryNodes(); DAInt fNodes1 = fNodes->buildSubstraction(notDuplSkin); - // Also, in this (segment) mesh, nodes connected to more than 3 segs should not be dup either (singular points - see testBuildInnerBoundary6()) - dt0=DataArrayIdType::New(),dit0=DataArrayIdType::New(),rdt0=DataArrayIdType::New(),rdit0=DataArrayIdType::New(); - MCUMesh meshM2Desc = meshM2->buildDescendingConnectivity(dt0, dit0, rdt0, rdit0); dt0=0; dit0=0; rdt0=0; // a mesh made of node cells - dsi = rdit0->deltaShiftIndex(); - DAInt singPoints = dsi->findIdsNotInRange(-1,4); // points connected to (strictly) more than 3 segments - const mcIdType *cc = meshM2Desc->getNodalConnectivity()->begin(), *ccI = meshM2Desc->getNodalConnectivityIndex()->begin(); - mcIdType * singPointsP = singPoints->rwBegin(); - for (mcIdType j=0; j < singPoints->getNumberOfTuples(); j++) // replace ids in singPoints by real coordinate index (was index of cells in notDuplSkin) + // Specific logic to handle singular points : + // - take the sub-mesh of M1 (dim N-1) built keeping only elements touching the m1IntersecSkin + // - build its spread zones + // - a node common to two different spread zones actually connects two cells of M1 by just one point : this is a singular point + // which should not be duplicated. + // This is a costly algorithm so only go into it if a simple (non sufficient) criteria is met: a node connected to more than 3 segs in meshM2: + dnu1=DataArrayIdType::New(), dnu2=DataArrayIdType::New(), dnu3=DataArrayIdType::New(), rdit0=DataArrayIdType::New(); + MCUMesh meshM2Desc = meshM2->buildDescendingConnectivity(dnu1, dnu2, dnu3, rdit0); // a mesh made of node cells + dnu1=0;dnu2=0;dnu3=0; + dsi = rdit0->deltaShiftIndex(); rdit0=0; + DAInt singPoints = dsi->findIdsNotInRange(-1,4) ; dsi=0;// points connected to (strictly) more than 3 segments + if (singPoints->getNumberOfTuples()) { - mcIdType nodeCellIdx = singPointsP[j]; - singPointsP[j] = cc[ccI[nodeCellIdx]+1]; // +1 to skip type + DAInt boundNodes = m1IntersecSkin->computeFetchedNodeIds(); + DAInt boundCells = otherDimM1OnSameCoords.getCellIdsLyingOnNodes(boundNodes->begin(), boundNodes->end(), false); // false= take cell in, even if not all nodes are in dupl + MCUMesh m1Bound = static_cast(otherDimM1OnSameCoords.buildPartOfMySelf(boundCells->begin(), boundCells->end(), true)); + DAInt d=DataArrayIdType::New(), dI=DataArrayIdType::New(), revD=DataArrayIdType::New(), revDI=DataArrayIdType::New(); + MCUMesh dnuM = m1Bound->buildDescendingConnectivity(d,dI,revD,revDI); dnuM = 0; + DataArrayIdType *tmp3=0, *tmp4=0; + MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(d,dI,revD,revDI, tmp3, tmp4 ); + DAInt neighSing(tmp3), neighISing(tmp4); + mcIdType seed=0; + DAInt hitCells = DataArrayIdType::New(); hitCells->alloc(m1Bound->getNumberOfCells(),1); hitCells->fillWithValue(-1); + mcIdType nIter=0, nIterMax=m1Bound->getNumberOfCells()+1; + while (nIter < nIterMax) + { + mcIdType dnuId; + DAInt sprdZone = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed,&seed+1, neighSing,neighISing, -1, dnuId); + const mcIdType * ptr = sprdZone->begin(); + for (mcIdType cnt = 0; cnt < sprdZone->getNumberOfTuples(); ptr++, cnt++) + hitCells->setIJSilent(*ptr,0,nIter); + nIter++; + DAInt noHit = hitCells->findIdsEqual(-1); + if (noHit->getNumberOfTuples()) + seed = noHit->getIJ(0,0); + else + break; + } + if (nIter >= nIterMax) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate(): internal error - too many iterations."); + DAInt uniq = hitCells->buildUniqueNotSorted(); + if (uniq->getNumberOfTuples() > 1) + { + // All points common to two (or more) different spread zones are singular: + DAInt cc=DataArrayIdType::New(), ccI=DataArrayIdType::New(); + m1Bound->getReverseNodalConnectivity(cc, ccI); + DAInt spreadCC = cc->deepCopy(); + spreadCC->transformWithIndArr(hitCells->begin(), hitCells->end()); + DAInt singPoints2 = DataArrayIdType::New(); singPoints2->alloc(0,1); + const mcIdType* ccIP = ccI->begin(); + const mcIdType* spreadCCP = spreadCC->begin(); + for(mcIdType j=0; j < ccI->getNumberOfTuples()-1; j++, ccIP++) + { + mcIdType sz = *(ccIP+1)-*ccIP; + if (sz == 0) continue; // skip empty packs + mcIdType val = spreadCCP[*ccIP]; + for (mcIdType k=1; k < sz; k++) + if (val != spreadCCP[*ccIP + k]) + { + singPoints2->pushBackSilent(j); + break; + } + } + fNodes1 = fNodes1->buildSubstraction(singPoints2); + } } - DAInt fNodes2 = fNodes1->buildSubstraction(singPoints); notDup = xtrem->buildSubstraction(fNodes1); } - else + else // if (validIds-> ...) notDup = xtrem->buildSubstraction(fNodes); } - else + else // if (3D ...) notDup = xtrem->buildSubstraction(fNodes); // Now compute cells around group (i.e. cells where we will do the propagation to identify the two sub-sets delimited by the group) DAInt m1Nodes = otherDimM1OnSameCoords.computeFetchedNodeIds(); DAInt dupl = m1Nodes->buildSubstraction(notDup); - DAInt cellsAroundGroup = getCellIdsLyingOnNodes(dupl->begin(), dupl->end(), false); // false= take cell in, even if not all nodes are in dupl + return dupl.retn(); +} + + +/*! + * This method expects that \b this and \b otherDimM1OnSameCoords share the same coordinates array. + * otherDimM1OnSameCoords->getMeshDimension() is expected to be equal to this->getMeshDimension()-1. + * This method is part of the MEDFileUMesh::buildInnerBoundaryAlongM1Group() algorithm. + * Given a set of nodes to duplicate, this method identifies which cells should have their connectivity modified + * to produce the inner boundary. It is typically called after findNodesToDuplicate(). + * + * \param [in] otherDimM1OnSameCoords a mesh lying on the same coords than \b this and with a mesh dimension equal to those of \b this minus 1. WARNING this input + * parameter is altered during the call. + * \param [in] nodeIdsToDuplicateBg node ids needed to be duplicated, as returned by findNodesToDuplicate. + * \param [in] nodeIdsToDuplicateEnd node ids needed to be duplicated, as returned by findNodesToDuplicate. + * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed. + * \param [out] cellIdsNotModified cell ids in \b this that lies on \b otherDimM1OnSameCoords mesh whose connectivity do \b not need to be modified as it is the case for \b cellIdsNeededToBeRenum. + * + */ +void MEDCouplingUMesh::findCellsToRenumber(const MEDCouplingUMesh& otherDimM1OnSameCoords, const mcIdType *nodeIdsToDuplicateBg, const mcIdType *nodeIdsToDuplicateEnd, + DataArrayIdType *& cellIdsNeededToBeRenum, DataArrayIdType *& cellIdsNotModified) const +{ + using DAInt = MCAuto; + using MCUMesh = MCAuto; + + checkFullyDefined(); + otherDimM1OnSameCoords.checkFullyDefined(); + if(getCoords()!=otherDimM1OnSameCoords.getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellsToRenumber: meshes do not share the same coords array !"); + if(otherDimM1OnSameCoords.getMeshDimension()!=getMeshDimension()-1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellsToRenumber: the mesh given in other parameter must have this->getMeshDimension()-1 !"); + + DAInt cellsAroundGroup = getCellIdsLyingOnNodes(nodeIdsToDuplicateBg, nodeIdsToDuplicateEnd, false); // false= take cell in, even if not all nodes are in dupl // MCUMesh mAroundGrp=static_cast(buildPartOfMySelf(cellsAroundGroup->begin(),cellsAroundGroup->end(),true)); - mcIdType nCells2 = mAroundGrp->getNumberOfCells(); + mcIdType nCells2 = mAroundGrp->getNumberOfCells(); DAInt desc00=DataArrayIdType::New(),descI00=DataArrayIdType::New(),revDesc00=DataArrayIdType::New(),revDescI00=DataArrayIdType::New(); MCUMesh mArGrpDesc=mAroundGrp->buildDescendingConnectivity(desc00,descI00,revDesc00,revDescI00); - // Neighbor information of the mesh without considering the crack (serves to count how many connex pieces it is made of) - DataArrayIdType *tmp00=0,*tmp11=0; - MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00, tmp00, tmp11); - DAInt neighInit00(tmp00); - DAInt neighIInit00(tmp11); + // Identify cells of M1 group in sub-mesh mAroundGrp + DataArrayIdType *idsOfM1t; + mArGrpDesc->areCellsIncludedIn(&otherDimM1OnSameCoords,2, idsOfM1t); + DAInt idsOfM1(idsOfM1t); + + // Build map giving for each cell ID in mAroundGrp the corresponding cell ID on the other side of the crack: + // Note that this does not cover all cells around the crack (a cell like a triangle might touche the crack only with its tip) + std::map toOtherSide; + const mcIdType *revDP=revDesc00->begin(), *revDIP=revDescI00->begin(); + for (const auto& v: *idsOfM1) + { + mcIdType idx0 = revDIP[v]; + mcIdType c1=revDP[idx0], c2=revDP[idx0+1]; + toOtherSide[c1] = c2; + toOtherSide[c2] = c1; + } + // Neighbor information of the mesh WITH the crack (some neighbors are removed): - DataArrayIdType *idsTmp=0; - mArGrpDesc->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsTmp); - DAInt ids(idsTmp); // In the neighbor information remove the connection between high dimension cells and its low level constituents which are part // of the frontier given in parameter (i.e. the cells of low dimension from the group delimiting the crack): - DataArrayIdType::RemoveIdsFromIndexedArrays(ids->begin(),ids->end(),desc00,descI00); - DataArrayIdType *tmp0=0,*tmp1=0; + DataArrayIdType::RemoveIdsFromIndexedArrays(idsOfM1->begin(), idsOfM1->end(),desc00,descI00); // Compute the neighbor of each cell in mAroundGrp, taking into account the broken link above. Two // cells on either side of the crack (defined by the mesh of low dimension) are not neighbor anymore. - ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00,tmp0,tmp1); - DAInt neigh00(tmp0); - DAInt neighI00(tmp1); + DataArrayIdType *neigh00t=0, *neighI00t=0; + MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00, neigh00t, neighI00t); + DAInt neigh00(neigh00t), neighI00(neighI00t); // For each initial connex part of the M1 mesh (or said differently for each independent crack): - mcIdType seed = 0, nIter = 0; + mcIdType seed=0, nIter=0; mcIdType nIterMax = nCells2+1; // Safety net for the loop - DAInt hitCells = DataArrayIdType::New(); hitCells->alloc(nCells2); - hitCells->fillWithValue(-1); - DAInt cellsToModifyConn0_torenum = DataArrayIdType::New(); - cellsToModifyConn0_torenum->alloc(0,1); + DAInt hitCells = DataArrayIdType::New(); hitCells->alloc(nCells2,1); + hitCells->fillWithValue(-1); // -1 : not hit, 0: one side of the crack, 1: other side of the crack + mcIdType PING_FULL, PONG_FULL; while (nIter < nIterMax) { DAInt t = hitCells->findIdsEqual(-1); - if (!t->getNumberOfTuples()) + if(!t->getNumberOfTuples()) break; - // Connex zone without the crack (to compute the next seed really) - mcIdType dnu; - DAInt connexCheck = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neighInit00,neighIInit00, -1, dnu); - mcIdType cnt(0); - for (mcIdType * ptr = connexCheck->getPointer(); cnt < connexCheck->getNumberOfTuples(); ptr++, cnt++) - hitCells->setIJ(*ptr,0,1); - // Connex zone WITH the crack (to identify cells lying on either part of the crack) - DAInt spreadZone = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neigh00,neighI00, -1, dnu); - cellsToModifyConn0_torenum = DataArrayIdType::Aggregate(cellsToModifyConn0_torenum, spreadZone, 0); - // Compute next seed, i.e. a cell in another connex part, which was not covered by the previous iterations - DAInt comple = cellsToModifyConn0_torenum->buildComplement(nCells2); + mcIdType seed = t->getIJ(0,0); + bool done = false; + PING_FULL =1; PONG_FULL=2; + mcIdType PING_PART=11, PONG_PART=22; + // while the connex bits in correspondance on either side of the crack are not fully covered + while(!done && nIter < nIterMax) // Start of the ping-pong + { + nIter++; + // Identify connex zone around the seed - this zone corresponds to some cells on the other side + // of the crack that might extend further away. So we will need to compute spread zone on the other side + // too ... and this process can repeat, hence the "ping-pong" logic. + mcIdType dnu; + DAInt spreadZone = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neigh00,neighI00, -1, dnu); + done = true; + mcIdType* hitCellsP = hitCells->rwBegin(); + for(const mcIdType& s: *spreadZone) + { + hitCellsP[s] = PING_FULL; + const auto& it = toOtherSide.find(s); + if (it != toOtherSide.end()) + { + mcIdType other = it->second; + if (hitCellsP[other] != PONG_FULL) + { + // On the other side of the crack we hit a cell which was not fully covered previously by the + // ComputeSpreadZone process, so we are not done yet, ComputeSreadZone will need to be applied there + done = false; + hitCellsP[other] = PONG_PART; + // Compute next seed, i.e. a cell on the other side of the crack + seed = other; + } + } + } + if (done) + { + // we might have several disjoint PONG parts in front of a single PING connex part: + DAInt idsPong = hitCells->findIdsEqual(PONG_PART); + if (idsPong->getNumberOfTuples()) + { + seed = idsPong->getIJ(0,0); + done = false; + } + continue; // continue without switching side (or break if 'done' remains false) + } + else + { + // Go to the other side + std::swap(PING_FULL, PONG_FULL); + std::swap(PING_PART, PONG_PART); + } + } // while (!done ...) DAInt nonHitCells = hitCells->findIdsEqual(-1); - DAInt intersec = nonHitCells->buildIntersection(comple); - if (intersec->getNumberOfTuples()) - { seed = intersec->getIJ(0,0); } + if (nonHitCells->getNumberOfTuples()) + seed = nonHitCells->getIJ(0,0); else - { break; } - nIter++; - } + break; + } // while (nIter < nIterMax ... if (nIter >= nIterMax) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate(): internal error - too many iterations."); - - DAInt cellsToModifyConn1_torenum=cellsToModifyConn0_torenum->buildComplement(neighI00->getNumberOfTuples()-1); - cellsToModifyConn0_torenum->transformWithIndArr(cellsAroundGroup->begin(),cellsAroundGroup->end()); - cellsToModifyConn1_torenum->transformWithIndArr(cellsAroundGroup->begin(),cellsAroundGroup->end()); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellsToRenumber: Too many iterations - should not happen"); + + DAInt cellsRet1 = hitCells->findIdsEqual(PONG_FULL); + DAInt cellsRet2 = hitCells->findIdsEqual(PING_FULL); + if (cellsRet1->getNumberOfTuples() + cellsRet2->getNumberOfTuples() != cellsAroundGroup->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellsToRenumber: Some cells not hit - Internal error should not happen"); + cellsRet1->transformWithIndArr(cellsAroundGroup->begin(),cellsAroundGroup->end()); + cellsRet2->transformWithIndArr(cellsAroundGroup->begin(),cellsAroundGroup->end()); // - cellIdsNeededToBeRenum=cellsToModifyConn0_torenum.retn(); - cellIdsNotModified=cellsToModifyConn1_torenum.retn(); - nodeIdsToDuplicate=dupl.retn(); + cellIdsNeededToBeRenum=cellsRet1.retn(); + cellIdsNotModified=cellsRet2.retn(); } /*! diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index de9c4da21..2d5f408d7 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -144,7 +144,8 @@ namespace MEDCoupling MEDCOUPLING_EXPORT DataArrayIdType *findCellIdsOnBoundary() const; MEDCOUPLING_EXPORT void findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayIdType *&cellIdsRk0, DataArrayIdType *&cellIdsRk1) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *computeSkin() const; - MEDCOUPLING_EXPORT void findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayIdType *& nodeIdsToDuplicate, + MEDCOUPLING_EXPORT DataArrayIdType *findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords) const; + MEDCOUPLING_EXPORT void findCellsToRenumber(const MEDCouplingUMesh& otherDimM1OnSameCoords, const mcIdType *nodeIdsToDuplicateBg, const mcIdType *nodeIdsToDuplicateEnd, DataArrayIdType *& cellIdsNeededToBeRenum, DataArrayIdType *& cellIdsNotModified) const; MEDCOUPLING_EXPORT void duplicateNodes(const mcIdType *nodeIdsToDuplicateBg, const mcIdType *nodeIdsToDuplicateEnd); MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(mcIdType offset); diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 1639e0751..c2f9afff3 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -365,6 +365,7 @@ typedef long int mcIdType; %newobject MEDCoupling::MEDCouplingUMesh::getRenumArrForMEDFileFrmt; %newobject MEDCoupling::MEDCouplingUMesh::convertCellArrayPerGeoType; %newobject MEDCoupling::MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec; +%newobject MEDCoupling::MEDCouplingUMesh::findNodesToDuplicate; %newobject MEDCoupling::MEDCouplingUMesh::buildDirectionVectorField; %newobject MEDCoupling::MEDCouplingUMesh::convertLinearCellsToQuadratic; %newobject MEDCoupling::MEDCouplingUMesh::getEdgeRatioField; @@ -2452,14 +2453,19 @@ namespace MEDCoupling return ret; } - PyObject *findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords) const + DataArrayIdType *findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords) const { - DataArrayIdType *tmp0=0,*tmp1=0,*tmp2=0; - self->findNodesToDuplicate(otherDimM1OnSameCoords,tmp0,tmp1,tmp2); - PyObject *ret=PyTuple_New(3); + DataArrayIdType *ret=self->findNodesToDuplicate(otherDimM1OnSameCoords); + return ret; + } + + PyObject *findCellsToRenumber(const MEDCouplingUMesh& otherDimM1OnSameCoords, const DataArrayIdType *dupNodes) const + { + DataArrayIdType *tmp0=0,*tmp1=0; + self->findCellsToRenumber(otherDimM1OnSameCoords,dupNodes->begin(), dupNodes->end(), tmp0,tmp1); + PyObject *ret=PyTuple_New(2); PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTITraits::TI, SWIG_POINTER_OWN | 0 )); PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTITraits::TI, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(tmp2),SWIGTITraits::TI, SWIG_POINTER_OWN | 0 )); return ret; } diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 214d44349..78460bf1c 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -4110,11 +4110,16 @@ void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, MUMesh m1=getMeshAtLevel(-1); mcIdType nbNodes=m0->getNumberOfNodes(); MUMesh m11=getGroup(-1,grpNameM1); - DataArrayIdType *tmp00=0,*tmp11=0,*tmp22=0; - m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22); // the core of the duplication logic is in this method - DAInt nodeIdsToDuplicate(tmp00); + DataArrayIdType *tmp00=0, *tmp11=0,*tmp22=0; + + // !!! The core of the duplication logic is in these 2 methods: + // !!! + DAInt nodeIdsToDuplicate = m0->findNodesToDuplicate(*m11); // identify nodes to duplicate + m0->findCellsToRenumber(*m11, nodeIdsToDuplicate->begin(), nodeIdsToDuplicate->end(), tmp11,tmp22); // identify cells needing renumbering DAInt cellsToModifyConn0(tmp11); DAInt cellsToModifyConn1(tmp22); + // !!!! + MUMesh tmp0=static_cast(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true)); // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1 DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New(); diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index 92c906a1e..5960607e4 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -1665,8 +1665,8 @@ class MEDLoaderTest3(unittest.TestCase): self.assertEqual(m3_bis.getCoords()[nodesDup].getValues(), m3_bis.getCoords()[nNod:].getValues()) self.assertEqual(set([4, 5, 6, 7, 20, 21, 22, 23, 32, 33, 34, 35]), set(cells1.getValues())) self.assertEqual(set([0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31]), set(cells2.getValues())) - self.assertEqual([],mfu.getGroupArr(-1,"group").getValues()) - self.assertEqual([],mfu.getGroupArr(-1,"group_dup").getValues()) # here only one cell has been duplicated + self.assertEqual([2, 7, 12, 17, 95, 99, 103, 107, 129, 133, 137, 141],mfu.getGroupArr(-1,"group").getValues()) + self.assertEqual([151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162],mfu.getGroupArr(-1,"group_dup").getValues()) # here only one cell has been duplicated m_desc, _, _, _, _ = m3_bis.buildDescendingConnectivity() m_desc.checkDeepEquivalOnSameNodesWith(m2_bis, 2, 9.9999) pass