Salome HOME
OverlapDEC: bug fix. Bounding box adjustment was negative.
[modules/med.git] / src / MEDCoupling / MEDCouplingAMRAttribute.cxx
index d78f2a58d2dabf60374e72256e420ac661986b07..f49b7bf9d7e456622bb9d08625be607a14acb25f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 #include "MEDCouplingIMesh.hxx"
 
 #include <sstream>
+#include <fstream>
 
 using namespace ParaMEDMEM;
 
+/// @cond INTERNAL
 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
 {
   return new DataArrayDoubleCollection(fieldNames);
@@ -328,15 +330,11 @@ std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
   return ret;
 }
 
-std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
+std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
   for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
-    {
-      const DataArrayDouble *pt((*it).first);
-      if(pt)
-        ret.push_back(pt);
-    }
+    ret.push_back((const DataArrayDouble *)(*it).first);
   return ret;
 }
 
@@ -709,15 +707,11 @@ std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
-    {
-      const DataArrayDoubleCollection *col((*it).second);
-      if(col)
-        ret.push_back(col);
-    }
+    ret.push_back((const DataArrayDoubleCollection *)(*it).second);
   return ret;
 }
 
@@ -734,6 +728,8 @@ void MEDCouplingGridCollection::updateTime() const
     }
 }
 
+/// @endcond
+
 MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather()
 {
   return _gf;
@@ -969,7 +965,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 +995,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.
  *
@@ -1287,15 +1392,11 @@ std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
   return ret;
 }
 
-std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
+std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
-    {
-      const MEDCouplingGridCollection *elt(*it);
-      if(elt)
-        ret.push_back(elt);
-    }
+    ret.push_back((const MEDCouplingGridCollection *)*it);
   return ret;
 }