]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
VTHB write
authorgeay <anthony.geay@cea.fr>
Mon, 7 Jul 2014 10:11:49 +0000 (12:11 +0200)
committergeay <anthony.geay@cea.fr>
Mon, 7 Jul 2014 10:11:49 +0000 (12:11 +0200)
src/MEDCoupling/MEDCouplingAMRAttribute.cxx
src/MEDCoupling/MEDCouplingAMRAttribute.hxx
src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx
src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i

index d78f2a58d2dabf60374e72256e420ac661986b07..7f8b5298f6cbcfbc11903e79643cd36631b8bf64 100644 (file)
@@ -24,6 +24,7 @@
 #include "MEDCouplingIMesh.hxx"
 
 #include <sstream>
+#include <fstream>
 
 using namespace ParaMEDMEM;
 
@@ -969,7 +970,6 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCo
  */
 MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const
 {
-  //tony
   const DataArrayDouble *arr(0);
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
     {
@@ -1000,12 +1000,122 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(ME
   return ret.retn();
 }
 
-/*!
- * This method is useful just after a remesh after a time step computation to project values in \a this to the new
- * mesh \a targetGF.
- *
- * This method performs a projection from \a this to a target AMR mesh \a targetGF.
- * This method performs the projection by trying to transfer the finest information to \a targetGF.
+
+std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const
+{
+  static const char EXT[]=".vthb";
+  std::string baseName,extName,zeFileName;
+  MEDCouplingMesh::SplitExtension(fileName,baseName,extName);
+  if(extName==EXT)
+    zeFileName=fileName;
+  else
+    { zeFileName=baseName; zeFileName+=EXT; }
+  //
+  std::ofstream ofs(fileName.c_str());
+  ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
+  const MEDCouplingCartesianAMRMesh *gf(getMyGodFather());
+  ofs << "  <vtkOverlappingAMR origin=\"";
+  const MEDCouplingIMesh *gfm(gf->getImageMesh());
+  std::vector<double> orig(gfm->getOrigin());
+  std::vector<double> spacing(gfm->getDXYZ());
+  int dim((int)orig.size());
+  std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\"";
+  for(int i=0;i<dim;i++)
+    {
+      char tmp[2]; tmp[0]='X'+i; tmp[1]='\0';
+      ofs << tmp;
+    }
+  ofs << "\">\n";
+  //
+  int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0);
+  for(int i=0;i<maxLev;i++)
+    {
+      std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
+      std::size_t sz(patches.size());
+      std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz);
+      for(std::size_t j=0;j<sz;j++)
+        patchesSafe[j]=patches[j];
+      if(sz==0)
+        continue;
+      ofs << "    <Block level=\"" << i << "\" spacing=\"";
+      std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," "));
+      ofs << "\">\n";
+      if(i!=maxLev-1)
+        {
+          std::vector<int> factors(patches[0]->getMesh()->getFactors());
+          for(int k=0;k<dim;k++)
+            spacing[k]*=1./((double) factors[k]);
+        }
+      std::size_t jj(0);
+      for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++)
+        {
+          ofs << "      <DataSet index=\"" << jj << "\" amr_box=\"";
+          const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it));
+          const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh());
+          if(patchCast)
+            {
+              const std::vector< std::pair<int,int> >& bltr(patchCast->getBLTRRangeRelativeToGF());
+              for(int pp=0;pp<dim;pp++)
+                ofs << bltr[pp].first << " " << bltr[pp].second-1 << " ";
+            }
+          else
+            {
+              const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh());
+              std::vector<int> cgs(im->getCellGridStructure());
+              for(int pp=0;pp<dim;pp++)
+                ofs << "0 " << cgs[pp]-1 << " ";
+            }
+          ofs << "\" file=\"";
+          //
+          int tmp(-1);
+          if(_levs[i]->presenceOf((*it)->getMesh(),tmp))
+            {
+              const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp));
+              std::vector<DataArrayDouble *> arrs(ddc.retrieveFields());
+              std::size_t nbFields(arrs.size());
+              std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields);
+              std::vector< const MEDCouplingFieldDouble *> fields(nbFields);
+              std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > fieldsSafe(nbFields);
+              for(std::size_t pp=0;pp<nbFields;pp++)
+                arrsSafe[pp]=arrs[pp];
+              for(std::size_t pp=0;pp<nbFields;pp++)
+                {
+                  MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev));
+                  std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure());
+                  arrs2Safe[pp]=DataArrayDouble::New();
+                  arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents());
+                  std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
+                  MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
+                  std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
+                  MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors);
+                  arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]);
+                  //
+                  fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp];
+                  fieldsSafe[pp]->setMesh(mesh->getImageMesh());
+                  fieldsSafe[pp]->setArray(arrs2Safe[pp]);
+                  fieldsSafe[pp]->setName(arrs[pp]->getName());
+                }
+              std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti";
+              MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true);
+              //
+              ofs << vtiFileName.str() << "\">\n";
+              ofs << "      \n      </DataSet>\n";
+            }
+        }
+      ofs << "    </Block>\n";
+    }
+  //
+  ofs << "  </vtkOverlappingAMR>\n";
+  ofs << "</VTKFile>\n";
+  return zeFileName;
+}
+
+  /*!
+   * This method is useful just after a remesh after a time step computation to project values in \a this to the new
+   * mesh \a targetGF.
+   *
+   * This method performs a projection from \a this to a target AMR mesh \a targetGF.
+   * This method performs the projection by trying to transfer the finest information to \a targetGF.
  * \b WARNING this method does not update the ghost zone, if any.
  * The level0 of \a this god father must have the same structure than those of \a targetGF.
  *
index 861c0b5ec7779efbed7c1d69d417490a2f7297ec..37857698a75a4624f3c4751130c4647ae5324317 100644 (file)
@@ -144,6 +144,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
+    MEDCOUPLING_EXPORT std::string writeVTHB(const std::string& fileName) const;
     //
     MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *projectTo(MEDCouplingCartesianAMRMesh *targetGF) const;
     //
index 68b90c7503c1215bb24fe057b68e0a7a4d8b67ca..84a89c51699bfabd1e20b96d9db5fd566b7c4599 100644 (file)
@@ -193,6 +193,43 @@ bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodDiffLev(const MEDCouplingCa
   return IsInMyNeighborhood(ghostLev>0?1:0,thispp,otherpp);//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors
 }
 
+std::vector< std::pair<int,int> > MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF() const
+{
+  std::vector< std::pair<int,int> > ret(_bl_tr);
+  const MEDCouplingCartesianAMRMeshGen *mesh(getMesh());
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF : not valid !");
+  const MEDCouplingCartesianAMRMeshGen *fath(mesh->getFather());
+  if(!fath)
+    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF : not valid 2 !");
+  std::vector<int> factors(fath->getFactors());
+  std::size_t sz(ret.size());
+  for(std::size_t ii=0;ii<sz;ii++)
+    {
+      ret[ii].first*=factors[ii];
+      ret[ii].second*=factors[ii];
+    }
+  const MEDCouplingCartesianAMRMeshGen *oldFather(fath);
+  fath=oldFather->getFather();
+  while(fath)
+    {
+      int pos(fath->getPatchIdFromChildMesh(oldFather));
+      const MEDCouplingCartesianAMRPatch *p(fath->getPatch(pos));
+      const std::vector< std::pair<int,int> >& tmp(p->getBLTRRange());
+      const std::vector<int>& factors2(fath->getFactors());
+      std::transform(factors.begin(),factors.end(),factors2.begin(),factors.begin(),std::multiplies<int>());
+      for(std::size_t ii=0;ii<sz;ii++)
+        {
+          int delta(ret[ii].second-ret[ii].first);
+          ret[ii].first+=tmp[ii].first*factors[ii];
+          ret[ii].second=ret[ii].first+delta;
+        }
+      oldFather=fath;
+      fath=oldFather->getFather();
+    }
+  return ret;
+}
+
 std::vector<int> MEDCouplingCartesianAMRPatch::computeCellGridSt() const
 {
   const MEDCouplingCartesianAMRMeshGen *m(getMesh());
index a8eecc4e13483d59b6e865d9928cb4a6d0578386..bee12ea855b402899c0f3a4e211624dca307addb 100644 (file)
@@ -82,6 +82,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT bool isInMyNeighborhoodDiffLev(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const;
     // basic set/get
     MEDCOUPLING_EXPORT const std::vector< std::pair<int,int> >& getBLTRRange() const { return _bl_tr; }
+    MEDCOUPLING_EXPORT std::vector< std::pair<int,int> > getBLTRRangeRelativeToGF() const;
     MEDCOUPLING_EXPORT std::vector<int> computeCellGridSt() const;
     MEDCOUPLING_EXPORT static bool IsInMyNeighborhood(int ghostLev, const std::vector< std::pair<int,int> >& p1, const std::vector< std::pair<int,int> >& p2);
     //
index a81eebcb303e2ae3d10fa487c12f6a0b93d1a351..691a760c14bca394e771859be66274dbbed76790 100644 (file)
@@ -15626,6 +15626,27 @@ class MEDCouplingBasicsTest(unittest.TestCase):
             self.assertTrue(att.getFieldOn(amr[1].getMesh(),"YY").isEqualWithoutConsideringStr(exp1,1e-12))
             pass
         pass
+    
+    def testSwig2AMR14(self):
+        """ non regression linked to VTHB write."""
+        fact=[2,2] ; fact2=[3,3]
+        amr=MEDCouplingCartesianAMRMesh("mesh",2,[5,5],[0.,0.],[1.,1.])
+        amr.addPatch([(1,3),(0,2)],fact)
+        amr.addPatch([(1,3),(3,4)],fact)
+        amr[0].addPatch([(1,3),(1,3)],fact2)
+        amr[1].addPatch([(1,3),(1,2)],fact2)
+        att=MEDCouplingAMRAttribute(amr,[("YY",1)],2)
+        att.alloc()
+        att.getFieldOn(amr,"YY").iota(0.1)
+        att.getFieldOn(amr[0].getMesh(),"YY").iota(0.2)
+        att.getFieldOn(amr[1].getMesh(),"YY").iota(0.3)
+        att.getFieldOn(amr[0][0].getMesh(),"YY").iota(0.4)
+        att.getFieldOn(amr[1][0].getMesh(),"YY").iota(0.5)
+        self.assertEqual(amr[0].getBLTRRangeRelativeToGF(),[(2,6),(0,4)])
+        self.assertEqual(amr[1].getBLTRRangeRelativeToGF(),[(2,6),(6,8)])
+        self.assertEqual(amr[0][0].getBLTRRangeRelativeToGF(),[(9,15),(3,9)])
+        self.assertEqual(amr[1][0].getBLTRRangeRelativeToGF(),[(9,15),(21,24)])
+        pass
 
     def testSwig2Intersect2DMeshWith1DLine1(self):
         """A basic test with no colinearity between m1 and m2."""
index 4ff7649a6bc9fb3a2ee09302c4187f7edae1de67..cdacf6ec4b119bd35e3fff084354044d1f38ea82 100644 (file)
@@ -4904,6 +4904,12 @@ namespace ParaMEDMEM
         return convertFromVectorPairInt(ret);
       }
 
+      PyObject *getBLTRRangeRelativeToGF() const throw(INTERP_KERNEL::Exception)
+      {
+        std::vector< std::pair<int,int> > ret(self->getBLTRRangeRelativeToGF());
+        return convertFromVectorPairInt(ret);
+      }
+
       void addPatch(PyObject *bottomLeftTopRight, const std::vector<int>& factors) throw(INTERP_KERNEL::Exception)
       {
         std::vector< std::pair<int,int> > inp;
@@ -5222,6 +5228,7 @@ namespace ParaMEDMEM
     MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception);
     bool changeGodFather(MEDCouplingCartesianAMRMesh *gf) throw(INTERP_KERNEL::Exception);
     MEDCouplingAMRAttribute *projectTo(MEDCouplingCartesianAMRMesh *targetGF) const throw(INTERP_KERNEL::Exception);
+    std::string writeVTHB(const std::string& fileName) const throw(INTERP_KERNEL::Exception);
     %extend
     {
       static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception)