]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
[EDF10723] - MEDFileUMesh::linearToQuadratic and MEDFileUMesh::quadraticToLinear
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 5 May 2015 13:16:47 +0000 (15:16 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 5 May 2015 13:16:47 +0000 (15:16 +0200)
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py

index b3d9a9ee2dda8174abc1877850caf86d9fcc1340..66355a7dc44770bba2ca97bd4d0866471f271d82 100644 (file)
@@ -3793,6 +3793,143 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
   return ret.retn();
 }
 
+/*!
+ * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
+ * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
+ * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
+ *
+ * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple
+ *             corresponding quadratic cells. 1 is those creating the 'most' complex.
+ * \param [in] eps - detection threshold for coordinates.
+ * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
+ *
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
+ */
+MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
+  int initialNbNodes(getNumberOfNodes());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
+  {
+    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
+  }
+  DataArrayDouble *zeCoords(m0->getCoords());
+  ret->setMeshAtLevel(0,m0);
+  std::vector<int> levs(getNonEmptyLevels());
+  const DataArrayInt *famField(getFamilyFieldAtLevel(0));
+  if(famField)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+      ret->setFamilyFieldArr(0,famFieldCpy);
+    }
+  famField=getFamilyFieldAtLevel(1);
+  if(famField)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
+      fam->fillWithZero();
+      fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
+      ret->setFamilyFieldArr(1,fam);
+    }
+  ret->copyFamGrpMapsFrom(*this);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
+  for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
+    {
+      if(*lev==0)
+        continue;
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
+      {
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
+      }
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
+      DataArrayInt *b(0);
+      bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
+      if(!a)
+        {
+          std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      b->applyLin(1,initialNbNodes);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
+      std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
+      m1->renumberNodesInConn(renum->begin());
+      m1->setCoords(zeCoords);
+      ret->setMeshAtLevel(*lev,m1);
+      famField=getFamilyFieldAtLevel(*lev);
+      if(famField)
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+          ret->setFamilyFieldArr(*lev,famFieldCpy);
+        }
+    }
+  return ret.retn();
+}
+
+/*!
+ * This method converts all quadratic cells in \a this into linear cells.
+ * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
+ * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
+ *
+ * \param [in] eps - detection threshold for coordinates.
+ * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
+ *
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
+ */
+MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
+  m0->convertQuadraticCellsToLinear();
+  m0->zipCoords();
+  DataArrayDouble *zeCoords(m0->getCoords());
+  ret->setMeshAtLevel(0,m0);
+  std::vector<int> levs(getNonEmptyLevels());
+  const DataArrayInt *famField(getFamilyFieldAtLevel(0));
+  if(famField)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+      ret->setFamilyFieldArr(0,famFieldCpy);
+    }
+  famField=getFamilyFieldAtLevel(1);
+  if(famField)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
+      ret->setFamilyFieldArr(1,fam);
+    }
+  ret->copyFamGrpMapsFrom(*this);
+  for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
+    {
+      if(*lev==0)
+        continue;
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
+      m1->convertQuadraticCellsToLinear();
+      m1->zipCoords();
+      DataArrayInt *b(0);
+      bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
+      if(!a)
+        {
+          std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      m1->renumberNodesInConn(b->begin());
+      m1->setCoords(zeCoords);
+      ret->setMeshAtLevel(*lev,m1);
+      famField=getFamilyFieldAtLevel(*lev);
+      if(famField)
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+          ret->setFamilyFieldArr(*lev,famFieldCpy);
+        }
+    }
+  return ret.retn();
+}
+
 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
 {
   clearNonDiscrAttributes();
index 38304da2c258a381686f1ac031ce1ccfd7d373b7..5d9f354e5758d6eb34dcaa5cc889a6e9adfb98ca 100644 (file)
@@ -289,6 +289,8 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell);
     MEDLOADER_EXPORT DataArrayInt *zipCoords();
     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;
     // serialization
     MEDLOADER_EXPORT void serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
                                     std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD);
index 418765cd86909de708922ab17b671e21079e07c0..d3af1eed904aa11e1a31196f347669a1376be589 100644 (file)
@@ -113,6 +113,8 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileUMesh::zipCoords;
 %newobject ParaMEDMEM::MEDFileUMesh::buildExtrudedMesh;
 %newobject ParaMEDMEM::MEDFileUMesh::__getitem__;
+%newobject ParaMEDMEM::MEDFileUMesh::linearToQuadratic;
+%newobject ParaMEDMEM::MEDFileUMesh::quadraticToLinear;
 %newobject ParaMEDMEM::MEDFileCMesh::New;
 %newobject ParaMEDMEM::MEDFileCurveLinearMesh::New;
 %newobject ParaMEDMEM::MEDFileMeshMultiTS::New;
@@ -789,6 +791,8 @@ namespace ParaMEDMEM
     DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception);
     MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const throw(INTERP_KERNEL::Exception);
+    MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const throw(INTERP_KERNEL::Exception);
+    MEDFileUMesh *quadraticToLinear(double eps=1e-12) const throw(INTERP_KERNEL::Exception);
     %extend
        { 
          MEDFileUMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception)
index 9e2e48cc0384e38bbc69f1ab568573ecb9d2dbba..702bda90550f3ba664920da6d916aa7cd377b444 100644 (file)
@@ -4279,6 +4279,49 @@ class MEDLoaderTest(unittest.TestCase):
         field2=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm)
         self.assertTrue(field.isEqual(field2,1e-12,1e-12))
         pass
+
+    def testMEDFileUMeshLinearToQuadraticAndRev1(self):
+        meshName="mesh"
+        fileName="Pyfile90.med"
+        fileName2="Pyfile91.med"
+        arr=DataArrayDouble(5) ; arr.iota()
+        m=MEDCouplingCMesh() ; m.setCoords(arr,arr)
+        m=m.buildUnstructured()
+        d=DataArrayInt([3,7,11,15])
+        m1=m[d]
+        m1.simplexize(0)
+        m2=m[d.buildComplement(m.getNumberOfCells())]
+        m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2)
+        m.changeSpaceDimension(3,0.)
+        arr=DataArrayDouble(3) ; arr.iota()
+        m1D=MEDCouplingCMesh() ; m1D.setCoords(arr) ; m1D=m1D.buildUnstructured() ; m1D.changeSpaceDimension(3,0.)
+        m1D.setCoords(m1D.getCoords()[:,[1,2,0]])
+        delta=m.getNumberOfNodes()*(m1D.getNumberOfNodes()-1)
+        m3D=m.buildExtrudedMesh(m1D,0)
+        m3D.sortCellsInMEDFileFrmt()
+        m3D.setName(meshName)
+        m2D=m ; m2D.setCoords(m3D.getCoords()) ; m2D.shiftNodeNumbersInConn(delta) ; m2D.setName(meshName) ; m2D.checkCoherency2()
+        m1D=m2D.computeSkin() ; m1D.setName(meshName)
+        #
+        mm=MEDFileUMesh()
+        mm[0]=m3D ; mm[-1]=m2D ; mm[-2]=m1D
+        grpEdge0=DataArrayInt([1,2,3,5]) ; grpEdge0.setName("East")
+        grpEdge1=DataArrayInt([0,1]) ; grpEdge1.setName("Corner1")
+        grpFaceSouth=DataArrayInt([0,1,8,9,10]) ; grpFaceSouth.setName("SouthFace")
+        grpFaceNorth=DataArrayInt([6,7,17,18,19]) ; grpFaceNorth.setName("NorthFace")
+        diagFace=DataArrayInt([0,1,13,15,17]) ; diagFace.setName("DiagFace")
+        vol1=DataArrayInt([20,21,23,24]) ; vol1.setName("vol1")
+        vol2=DataArrayInt([2,3,4,5,21,24]) ; vol2.setName("vol2")
+        mm.setGroupsAtLevel(0,[vol1,vol2])
+        mm.setGroupsAtLevel(-1,[grpFaceSouth,grpFaceNorth,diagFace])
+        mm.setGroupsAtLevel(-2,[grpEdge0,grpEdge1])
+        #
+        mmOut1=mm.linearToQuadratic(0,0.)
+        mmOut1.write(fileName2,2)
+        mmOut2=mmOut1.quadraticToLinear(0.)
+        self.assertTrue(mm.isEqual(mmOut2,1e-12)[0])
+        pass
+
     pass
 
 unittest.main()