Salome HOME
Merge branch 'master' of ssh://git.salome-platform.org/tools/medcoupling
[tools/medcoupling.git] / src / MEDLoader / MEDFileBlowStrEltUp.cxx
index 973f2b8ed447ba67aa250f4cf8c9f9ead8c0c1c9..8fa0d2d52bebee9a0144378989a9f757afd8df48 100644 (file)
@@ -21,6 +21,7 @@
 #include "MEDFileBlowStrEltUp.hxx"
 #include "MEDCouplingFieldDouble.hxx"
 #include "MEDFileFieldVisitor.hxx"
+#include "MEDCouplingPartDefinition.hxx"
 #include "MCAuto.txx"
 
 using namespace MEDCoupling;
@@ -315,10 +316,12 @@ public:
   bool isClassic() const { return _is_classic; }
   bool operator!=(const FieldWalker2& other) const;
   bool operator==(const FieldWalker2& other) const;
+  const SlicePartDefinition *getPartDef() const { return _pd; }
 private:
   std::string _loc;
   std::string _pfl;
   bool _is_classic;
+  MCAuto<SlicePartDefinition> _pd;
 };
 
 class LocInfo
@@ -329,27 +332,38 @@ public:
   bool operator==(const LocInfo& other) const { return _locs==other._locs && _pfl==other._pfl; }
   void push(const std::string& loc, const std::string& pfl) { checkUniqueLoc(loc); _locs.push_back(loc); _pfl.push_back(pfl); }
   MCAuto<MEDFileUMesh> generateNonClassicalData(int zePos, const MEDFileUMesh *mesh, const MEDFileFieldGlobsReal *globs) const;
+  const PartDefinition *getPartDef() const { return _pd; }
 private:
   void checkUniqueLoc(const std::string& loc) const;
   static MCAuto<DataArrayDouble> BuildMeshFromAngleVrille(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *angleDeVrille, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs);
+  static MCAuto<DataArrayDouble> BuildMeshFromEpaisseur(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *thikness, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs);
+  static MCAuto<MEDCouplingUMesh> BuildMeshCommon(INTERP_KERNEL::NormalizedCellType gt, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs, MCAuto<DataArrayDouble>& ptsForLoc);
   static MCAuto<DataArrayDouble> BuildMeshFromStructure(INTERP_KERNEL::NormalizedCellType gt, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs);
 public:
   static const char ANGLE_DE_VRILLE[];
+  static const char EPAISSEUR[];
 private:
   std::vector<std::string> _locs;
   std::vector<std::string> _pfl;
+  MCAuto<PartDefinition> _pd;
 };
 
 const char LocInfo::ANGLE_DE_VRILLE[]="ANGLE DE VRILLE";
 
+const char LocInfo::EPAISSEUR[]="EPAISSEUR";
+
 LocInfo::LocInfo(const std::vector<FieldWalker2>& fw)
 {
   std::size_t sz(fw.size());
   _locs.resize(sz); _pfl.resize(sz);
+  if(sz>0)
+    _pd=fw[0].getPartDef()->deepCopy();
   for(std::size_t i=0;i<sz;i++)
     {
       _locs[i]=fw[i].getLoc();
       _pfl[i]=fw[i].getPfl();
+      if(i>0)
+        _pd=(*_pd)+(*(fw[i].getPartDef()));
     }
 }
 
@@ -362,7 +376,7 @@ void LocInfo::checkUniqueLoc(const std::string& loc) const
     }
 }
 
-MCAuto<DataArrayDouble> LocInfo::BuildMeshFromAngleVrille(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *angleDeVrille, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs)
+MCAuto<MEDCouplingUMesh> LocInfo::BuildMeshCommon(INTERP_KERNEL::NormalizedCellType gt,const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs, MCAuto<DataArrayDouble>& ptsForLoc)
 {
   MCAuto<DataArrayInt> conn(zeStr->getConn());
   conn=conn->deepCopy(); conn->rearrange(1);
@@ -374,6 +388,19 @@ MCAuto<DataArrayDouble> LocInfo::BuildMeshFromAngleVrille(INTERP_KERNEL::Normali
     geoMesh=umesh->buildUnstructured();
   }
   //
+  MCAuto<MEDCouplingFieldDouble> fakeF(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
+  fakeF->setMesh(geoMesh);
+  fakeF->setGaussLocalizationOnType(gt,loc.getRefCoords(),loc.getGaussCoords(),loc.getGaussWeights());
+  ptsForLoc=fakeF->getLocalizationOfDiscr();
+  //
+  return geoMesh;
+}
+
+MCAuto<DataArrayDouble> LocInfo::BuildMeshFromAngleVrille(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *angleDeVrille, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs)
+{
+  MCAuto<DataArrayDouble> ptsForLoc;
+  MCAuto<MEDCouplingUMesh> geoMesh(BuildMeshCommon(gt,pfl,loc,zeStr,mesh,section,globs,ptsForLoc));
+  //
   MCConstAuto<DataArrayDouble> angleVrille;
   if(!pfl.empty())
     {
@@ -384,22 +411,17 @@ MCAuto<DataArrayDouble> LocInfo::BuildMeshFromAngleVrille(INTERP_KERNEL::Normali
   else
     angleVrille.takeRef(angleDeVrille);
   //
-  MCAuto<MEDCouplingFieldDouble> fakeF(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
-  fakeF->setMesh(geoMesh);
-  int nbg(loc.getGaussWeights().size());
-  fakeF->setGaussLocalizationOnType(gt,loc.getRefCoords(),loc.getGaussCoords(),loc.getGaussWeights());
-  MCAuto<DataArrayDouble> ptsForLoc(fakeF->getLocalizationOfDiscr());
-  //
-  MCAuto<MEDCouplingFieldDouble> dir(geoMesh->buildDirectionVectorField());
-  MCAuto<DataArrayDouble> rot(dir->getArray()->fromCartToSpher());
-  int nbCells(geoMesh->getNumberOfCells()),nbCompo(ptsForLoc->getNumberOfComponents());
+  int nbCompo(ptsForLoc->getNumberOfComponents());
   MCAuto<DataArrayDouble> secPts(section->getCoords()->changeNbOfComponents(nbCompo,0.));
-  int nbSecPts(secPts->getNumberOfTuples());
+  int nbSecPts(secPts->getNumberOfTuples()),nbCells(geoMesh->getNumberOfCells()),nbg(loc.getGaussWeights().size());
   {
     const int TAB[3]={2,0,1};
     std::vector<int> v(TAB,TAB+3);
     secPts=secPts->keepSelectedComponents(v);
   }
+  MCAuto<MEDCouplingFieldDouble> dir(geoMesh->buildDirectionVectorField());
+  MCAuto<DataArrayDouble> rot(dir->getArray()->fromCartToSpher());
+  //
   const double CENTER[3]={0.,0.,0.},AX0[3]={0.,0.,1.};
   double AX1[3]; AX1[2]=0.;
   std::vector< MCAuto<DataArrayDouble> > arrs(nbCells*nbg);
@@ -425,6 +447,49 @@ MCAuto<DataArrayDouble> LocInfo::BuildMeshFromAngleVrille(INTERP_KERNEL::Normali
   return resu;
 }
 
+MCAuto<DataArrayDouble> LocInfo::BuildMeshFromEpaisseur(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *thikness, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs)
+{
+  MCAuto<DataArrayDouble> ptsForLoc;
+  MCAuto<MEDCouplingUMesh> geoMesh(BuildMeshCommon(gt,pfl,loc,zeStr,mesh,section,globs,ptsForLoc));
+  int nbSecPts(section->getNumberOfNodes()),nbCells(geoMesh->getNumberOfCells()),nbg(loc.getGaussWeights().size());
+  MCConstAuto<DataArrayDouble> zeThikness;
+  if(!pfl.empty())
+    {
+      const DataArrayInt *pflArr(globs->getProfile(pfl));
+      geoMesh=geoMesh->buildPartOfMySelf(pflArr->begin(),pflArr->end(),true);
+      zeThikness=thikness->selectByTupleIdSafe(pflArr->begin(),pflArr->end());
+    }
+  else
+    zeThikness.takeRef(thikness);
+  MCAuto<DataArrayDouble> orthoArr;
+  {
+    MCAuto<MEDCouplingFieldDouble> ortho(geoMesh->buildOrthogonalField());
+    orthoArr.takeRef(ortho->getArray());
+  }
+  int nbCompo(orthoArr->getNumberOfComponents());
+  MCAuto<DataArrayDouble> secPts(section->getCoords()->duplicateEachTupleNTimes(nbCompo));
+  secPts->rearrange(nbCompo);
+  std::vector< MCAuto<DataArrayDouble> > arrs(nbCells*nbg);
+  for(int j=0;j<nbCells;j++)
+    {
+      double thck(zeThikness->getIJ(j,0));
+      MCAuto<DataArrayDouble> fact(DataArrayDouble::New()); fact->alloc(1,nbCompo);
+      std::copy(orthoArr->begin()+j*nbCompo,orthoArr->begin()+(j+1)*nbCompo,fact->getPointer());
+      std::transform(fact->begin(),fact->end(),fact->getPointer(),std::bind2nd(std::multiplies<double>(),thck/2.));
+      MCAuto<DataArrayDouble> p(DataArrayDouble::Multiply(secPts,fact));
+      for(int l=0;l<nbg;l++)
+        {
+          MCAuto<DataArrayDouble> p2(p->deepCopy());
+          for(int k=0;k<nbCompo;k++)
+            p2->applyLin(1.,ptsForLoc->getIJ(j*nbg+l,k),k);
+          arrs[j*nbg+l]=p2;
+        }
+    }
+  std::vector<const DataArrayDouble *> arrs2(VecAutoToVecOfCstPt(arrs));
+  MCAuto<DataArrayDouble> resu(DataArrayDouble::Aggregate(arrs2));
+  return resu;
+}
+
 MCAuto<DataArrayDouble> LocInfo::BuildMeshFromStructure(INTERP_KERNEL::NormalizedCellType gt, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs)
 {
   static const char MSG1[]="BuildMeshFromStructure : not recognized pattern ! Send mail to anthony.geay@edf.fr with corresponding MED file !";
@@ -437,9 +502,11 @@ MCAuto<DataArrayDouble> LocInfo::BuildMeshFromStructure(INTERP_KERNEL::Normalize
   MCAuto<DataArrayDouble> zeArr2(DynamicCast<DataArray,DataArrayDouble>(zeArr));
   if(zeArr2.isNull())
     throw INTERP_KERNEL::Exception(MSG1);
-  if(zeArr2->getName()!=ANGLE_DE_VRILLE)
-    throw INTERP_KERNEL::Exception(MSG1);
-  return BuildMeshFromAngleVrille(gt,zeArr2,pfl,loc,zeStr,mesh,section,globs);
+  if(zeArr2->getName()==ANGLE_DE_VRILLE)
+    return BuildMeshFromAngleVrille(gt,zeArr2,pfl,loc,zeStr,mesh,section,globs);
+  if(zeArr2->getName()==EPAISSEUR)
+    return BuildMeshFromEpaisseur(gt,zeArr2,pfl,loc,zeStr,mesh,section,globs);
+  throw INTERP_KERNEL::Exception(MSG1);
 }
 
 MCAuto<MEDFileUMesh> LocInfo::generateNonClassicalData(int zePos, const MEDFileUMesh *mesh, const MEDFileFieldGlobsReal *globs) const
@@ -505,17 +572,22 @@ FieldWalker2::FieldWalker2(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
   _loc=pmptpd->getLocalization();
   _pfl=pmptpd->getProfile();
   _is_classic=pmptpd->getType()!=ON_GAUSS_PT;
+  _pd=SlicePartDefinition::New(pmptpd->getStart(),pmptpd->getEnd(),1);
 }
 
 bool FieldWalker2::operator!=(const FieldWalker2& other) const
 {
-  bool ret(_loc==other._loc && _pfl==other._pfl && _is_classic==other._is_classic);
-  return !ret;
+  return !((*this)==other);
 }
 
 bool FieldWalker2::operator==(const FieldWalker2& other) const
 {
-  bool ret(_loc==other._loc && _pfl==other._pfl && _is_classic==other._is_classic);
+  bool ret2(false);
+  {
+    std::string tmp;
+    ret2=_pd->isEqual(other._pd,tmp);
+  }
+  bool ret(_loc==other._loc && _pfl==other._pfl && _is_classic==other._is_classic && ret2);
   return ret;
 }
 
@@ -755,7 +827,10 @@ void LocSpliter::generateNonClassicalData(const MEDFileUMesh *mesh, std::vector<
               int t2,t3;
               double t1(f1ts->getTime(t2,t3));
               MCAuto<MEDCouplingFieldDouble> mcf(MEDCouplingFieldDouble::New(ON_NODES));
-              mcf->setArray(f1ts->getUndergroundDataArray());
+              MCAuto<DataArrayDouble> arr,arr2;
+              arr.takeRef(f1ts->getUndergroundDataArray());
+              arr2=arr->selectPartDef((*it).getPartDef());
+              mcf->setArray(arr2);
               mcf->setTime(t1,t2,t3);
               mcf->setName(f1ts->getName());
               mcf->setMesh(mcm);
@@ -803,6 +878,23 @@ void LocSpliter::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDis
   _fw->newPerMeshPerTypePerDisc(pmptpd);
 }
 
+void MEDFileBlowStrEltUp::DealWithConflictNames(MEDFileAnyTypeFieldMultiTS *fmtsToAdd, const MEDFileFields *fs)
+{
+  std::vector<std::string> fnames(fs->getFieldsNames());
+  for(int i=0;i<1000;i++)
+    {
+      std::ostringstream oss; oss << fmtsToAdd->getName();
+      if(i>=1)
+        oss << "_" << i-1;
+      if(std::find(fnames.begin(),fnames.end(),oss.str())==fnames.end())
+        {
+          fmtsToAdd->setName(oss.str());
+          return ;
+        }
+    }
+  throw INTERP_KERNEL::Exception("DealWithConflictNames : Eh eh interesting !");
+}
+
 MCAuto<MEDFileFields> MEDFileBlowStrEltUp::splitFieldsPerLoc(const MEDFileFields *fields, const MEDFileUMesh *mesh, MEDFileMeshes *msOut, MEDFileFields *allZeOutFields)
 {
   LocSpliter ls(fields);
@@ -815,6 +907,7 @@ MCAuto<MEDFileFields> MEDFileBlowStrEltUp::splitFieldsPerLoc(const MEDFileFields
       for(int j=0;j<(*it)->getNumberOfFields();j++)
         {
           MCAuto<MEDFileAnyTypeFieldMultiTS> fmts((*it)->getFieldAtPos(j));
+          //DealWithConflictNames(fmts,allZeOutFields);// uncomment to have a writable data structure
           allZeOutFields->pushField(fmts);
         }
     }