]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
[EDF27988] : Add MEDFileUMesh.reduceToCells method and test on it agy/edf27988
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 11 Aug 2023 13:28:39 +0000 (15:28 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 11 Aug 2023 13:28:39 +0000 (15:28 +0200)
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/Swig/CMakeLists.txt
src/MEDLoader/Swig/MEDLoaderFinalize.i
src/MEDLoader/Swig/MEDLoaderFinalize.py [new file with mode: 0644]
src/MEDLoader/Swig/MEDLoaderTest3.py

index d00f5ba7ac6a4fc5b7116bfa03f21ea5f64245e4..4de31cc17a970646420b1d0edeaff5cf34b6b030 100644 (file)
@@ -4534,7 +4534,7 @@ DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<i
  * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
  * 
  * \return - a new reference of MEDFileUMesh
- * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
+ * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart, MEDFileUMesh.reduceToCells
  */
 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
 {
index 993625e66ec4a35298a659b7de4da41dc3a2102b..2cdbaa0f7e6693b6fd52c48ca254622a732aa1aa 100644 (file)
@@ -368,6 +368,7 @@ MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<Data
     MEDLOADER_EXPORT DataArrayIdType *computeFetchedNodeIds() const;
     MEDLOADER_EXPORT DataArrayIdType *deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const;
     MEDLOADER_EXPORT MEDFileUMesh *extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const;
+    // MCAuto<MEDFileUMesh> extractPart(int level, DataArrayIdType *keepCells, bool removeOrphanNodes = true) const; // implemented in python
     MEDLOADER_EXPORT MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const;
     MEDLOADER_EXPORT MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const;
     MEDLOADER_EXPORT MEDFileUMesh *quadraticToLinear(double eps=1e-12) const;
index d718bafb072addad82d53d4b79e03a5b6fbdfa9d..0cb6bc26d03ca380e1d215a0cf078da4ce0f4d42 100644 (file)
@@ -96,7 +96,7 @@ INSTALL(FILES MEDLoader.i MEDLoaderTypemaps.i MEDLoaderCommon.i MEDLoaderFinaliz
 
 SALOME_INSTALL_SCRIPTS(${CMAKE_CURRENT_BINARY_DIR}/MEDLoader.py ${MEDCOUPLING_INSTALL_PYTHON} EXTRA_DPYS "${SWIG_MODULE_MEDLoader_REAL_NAME}")
 
-INSTALL(FILES MEDLoaderSplitter.py DESTINATION ${MEDCOUPLING_INSTALL_PYTHON})
+INSTALL(FILES MEDLoaderSplitter.py MEDLoaderFinalize.py DESTINATION ${MEDCOUPLING_INSTALL_PYTHON})
 
 
 INSTALL(FILES ${ALL_TESTS} MEDLoaderDataForTest.py MEDLoaderTest1.py MEDLoaderTest2.py MEDLoaderTest3.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_SCRIPTS})
index c8fab8b86bf564032e85bed1bbea787f7a6cf9ed..84eecd379c2a7e3415c4f0a8ae03e40bcbfe349b 100644 (file)
@@ -19,6 +19,9 @@
 // Author : Anthony Geay (EDF R&D)
 
 %pythoncode %{
+import MEDLoaderFinalize
+MEDFileUMesh.reduceToCells = MEDLoaderFinalize.MEDFileUMeshReduceToCells
+del MEDLoaderFinalize
 MEDFileMeshesIterator.__next__ = MEDFileMeshesIterator.next
 MEDFileAnyTypeFieldMultiTSIterator.__next__ = MEDFileAnyTypeFieldMultiTSIterator.next
 MEDFileFieldsIterator.__next__ = MEDFileFieldsIterator.next
diff --git a/src/MEDLoader/Swig/MEDLoaderFinalize.py b/src/MEDLoader/Swig/MEDLoaderFinalize.py
new file mode 100644 (file)
index 0000000..c5689db
--- /dev/null
@@ -0,0 +1,66 @@
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2023  CEA, EDF
+#
+# 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, 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
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+def MEDFileUMeshReduceToCells(self, level, keepCells, removeOrphanNodes=True):
+    """
+    Method returning a new MEDFileUMesh, restriction of self to level and keepCell cells at this level.
+    This method also 
+
+    :param level: Specifies the top level of the returned MEDFileUMesh expected
+    :param keepCells: A DataArrayInt specifying cell ids at level level of self
+    :param removeOrphanNodes: Specifies if orphan nodes should be removed at the end
+    
+    see also MEDFileUMesh.extractPart
+    """
+    import MEDLoader as ml
+    subLevs = [l for l in self.getNonEmptyLevels() if l<=level]
+    subMeshes = [self[lev] for lev in subLevs]
+    allFamilyFields = [self.getFamilyFieldAtLevel(lev) for lev in subLevs]
+    allRefMesh = subMeshes[0]
+    refMesh = allRefMesh[keepCells]
+
+    mmOut = ml.MEDFileUMesh()
+    # level 0
+    mmOut[0] = refMesh
+    mmOut.setFamilyFieldArr(0,allFamilyFields[0][keepCells])
+
+    # subLevels
+    for curLev,meshLev,famFieldLev in zip(subLevs[1:],subMeshes[1:],allFamilyFields[1:]):
+        allMeshLev,d,di, rd,rdi = allRefMesh.explodeMeshTo( curLev-level )
+        a,b = allMeshLev.areCellsIncludedIn(meshLev,2)
+        if not a:
+            raise RuntimeError("Error in mesh {}")
+        dlev,dlevi = ml.DataArrayInt.ExtractFromIndexedArrays( keepCells, d,di )
+        dlev2 = dlev.buildUniqueNotSorted()
+        cellsToKeepLev = ml.DataArrayInt.BuildIntersection([dlev2,b])
+        cellsToKeepLev = b.indicesOfSubPart(cellsToKeepLev)
+        cellsToKeepLev.sort()
+        mmOut[curLev] = meshLev[cellsToKeepLev]
+        mmOut.setFamilyFieldArr(curLev,famFieldLev[cellsToKeepLev])
+
+    allFamNodes = mmOut.getFamilyFieldAtLevel(1)
+    if allFamNodes:
+        mmOut.setFamilyFieldArr(1,allFamNodes[:])
+
+    if removeOrphanNodes:
+        mmOut.zipCoords()
+
+    mmOut.copyFamGrpMapsFrom(self)
+    return mmOut
index d8afdb960b5b48c3d7d6e7ae12667709e8fa23ed..80a1b87aba5e512555ee76def0b0778ea45c6f5b 100644 (file)
@@ -7132,6 +7132,65 @@ class MEDLoaderTest3(unittest.TestCase):
 
         pass
 
+    def testUMeshReduceToCells(self):
+        """
+        [EDF27988] : test of MEDFileUMesh.reduceToCells method
+        """
+        arr = DataArrayDouble(4) ; arr.iota()
+        arrZ = DataArrayDouble(2) ; arrZ.iota()
+        m = MEDCouplingCMesh() ; m.setCoords(arr,arr,arrZ)
+        m = m.buildUnstructured()
+        mm = MEDFileUMesh()
+        mm[0] = m
+        m1 = m.buildDescendingConnectivity()[0]
+        bas1 = DataArrayInt([0,6,11,16,21,25,29,34,38])
+        haut1 = DataArrayInt([1,7,12,17,22,26,30,35,39])
+        lat1 = DataArrayInt([8,9,23,36])
+        allcellsInMM = DataArrayInt.Aggregate([bas1,haut1,lat1])
+        allcellsInMM.sort()
+        m1InMM = m1[allcellsInMM]
+        mm[-1] = m1InMM
+        bas1 = allcellsInMM.findIdForEach(bas1) ; bas1.setName("bas1")
+        haut1 = allcellsInMM.findIdForEach(haut1) ; haut1.setName("haut1")
+        lat1 = allcellsInMM.findIdForEach(lat1) ; lat1.setName("lat1")
+        m2 = m1InMM.buildDescendingConnectivity()[0]
+        lat2 = DataArrayInt( [ 14, 15, 16, 17, 34, 35, 50, 51] )
+        allCellsInMM2 = DataArrayInt( [4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 21, 22, 23, 27, 28, 29, 32, 33, 34, 35, 38, 39, 43, 44, 45, 48, 49, 50, 51, 54, 55] )
+        lat2 = allCellsInMM2.findIdForEach(lat2) ; lat2.setName("lat2")
+        m2InMM = m2[allCellsInMM2]
+        mm[-2] = m2InMM
+        mm.setName("mesh")
+        ##
+        bas1_id = -1 ; haut1_id = -2 ; lat1_id = -3 ; lat2_id = -4
+        fam0 = DataArrayInt( m.getNumberOfCells() ) ; fam0.iota()
+        mm.setFamilyFieldArr(0,fam0)
+        fam1 = DataArrayInt( m1InMM.getNumberOfCells() ) ; fam1[:] = 0 ; fam1[bas1] = bas1_id ; fam1[haut1] = haut1_id ; fam1[lat1] = lat1_id
+        mm.setFamilyFieldArr(-1,fam1)
+        fam2 = DataArrayInt( m2InMM.getNumberOfCells() ) ; fam2[:] = 0 ; fam2[lat2] = lat2_id
+        mm.setFamilyFieldArr(-2,fam2)
+        for grp,famid in [(bas1,bas1_id),(haut1,haut1_id),(lat1,lat1_id),(lat2,lat2_id)]:
+            mm.addFamily(grp.getName(),famid)
+            mm.setFamiliesIdsOnGroup(grp.getName(),[famid])
+        # ze heart of the test
+        mmr = mm.reduceToCells(0,DataArrayInt([4]))
+        # assert section
+        tmp = m[4] ; tmp.zipCoords()
+        self.assertTrue( mmr[0].isEqual(tmp,1e-12) )
+        tmp = MEDCoupling1SGTUMesh( mmr[-1] )
+        self.assertTrue( tmp.getCellModelEnum() == NORM_QUAD4 )
+        self.assertTrue( tmp.getNodalConnectivity().isEqual( DataArrayInt([0, 4, 5, 1, 1, 0, 2, 3, 5, 7, 6, 4, 2, 6, 7, 3]) ) )
+        tmp = MEDCoupling1SGTUMesh( mmr[-2] )
+        self.assertTrue( tmp.getCellModelEnum() == NORM_SEG2 )
+        self.assertTrue( tmp.getNodalConnectivity().isEqual( DataArrayInt([5, 4, 0, 4, 5, 1, 4, 6, 5, 7, 7, 6, 2, 6, 7, 3]) ) )
+        #
+        self.assertTrue( mmr.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([4])) )
+        self.assertTrue( mmr.getFamilyFieldAtLevel(-1).isEqual(DataArrayInt([-3, -1, -2, -3])) )
+        self.assertTrue( mmr.getFamilyFieldAtLevel(-2).isEqual(DataArrayInt([0, -4, -4, 0, 0, 0, -4, -4])) )
+        #
+        self.assertTrue( set( mm.getGroupsNames() ) == set( mmr.getGroupsNames() ) )
+        for grp in mm.getGroupsNames():
+            self.assertTrue( set(mm.getFamiliesIdsOnGroup(grp)) == set(mmr.getFamiliesIdsOnGroup(grp)) )
+
     pass
 
 if __name__ == "__main__":