Salome HOME
Some useful tools for MEDCouplingMappedExtrudedMesh users that needs to store it...
[tools/medcoupling.git] / src / MEDLoader / MEDFileMesh.cxx
index ce388ecac0790d91f1ec4931a32e4f61d82f4b2f..e71326cea842b29f3bacc290de538f6bf3df726c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2016  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
@@ -27,6 +27,7 @@
 #include "MEDLoaderBase.hxx"
 
 #include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingMappedExtrudedMesh.hxx"
 
 #include "InterpKernelAutoPtr.hxx"
 
@@ -39,6 +40,8 @@ using namespace MEDCoupling;
 
 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
 
+const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
+
 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
 {
 }
@@ -1432,11 +1435,10 @@ void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::stri
  */
 int MEDFileMesh::getFamilyId(const std::string& name) const
 {
-  std::string oname(name);
-  std::map<std::string, int>::const_iterator it=_families.find(oname);
-  std::vector<std::string> fams=getFamiliesNames();
+  std::map<std::string, int>::const_iterator it=_families.find(name);
   if(it==_families.end())
     {
+      std::vector<std::string> fams(getFamiliesNames());
       std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
       std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
       throw INTERP_KERNEL::Exception(oss.str().c_str());
@@ -2091,6 +2093,9 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() con
   return ret;
 }
 
+/*!
+ * \sa getAllDistributionOfTypes
+ */
 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
 {
   MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
@@ -2271,6 +2276,25 @@ MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSele
   return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
 }
 
+/*!
+ * \b WARNING this implementation is dependant from MEDCouplingMappedExtrudedMesh::buildUnstructured !
+ * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
+ */
+MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
+{
+  if(!mem)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
+  MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
+  m2D->zipCoords();
+  m2D->setCoords(m3D->getCoords());
+  ret->setMeshAtLevel(0,m3D);
+  ret->setMeshAtLevel(-1,m2D);
+  ret->setFamilyId(GetSpeStr4ExtMesh(),mem->get2DCellIdForExtrusion());
+  return ret.retn();
+}
+
 /*!
  * Returns an empty instance of MEDFileUMesh.
  *  \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
@@ -2336,7 +2360,7 @@ std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() c
   return ret;
 }
 
-MEDFileMesh *MEDFileUMesh::shallowCpy() const
+MEDFileUMesh *MEDFileUMesh::shallowCpy() const
 {
   MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
   return ret.retn();
@@ -2347,7 +2371,7 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const
   return new MEDFileUMesh;
 }
 
-MEDFileMesh *MEDFileUMesh::deepCopy() const
+MEDFileUMesh *MEDFileUMesh::deepCopy() const
 {
   MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
   ret->deepCpyEquivalences(*this);
@@ -3589,6 +3613,30 @@ MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_
   return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
 }
 
+/*!
+ * This method returns for each geo types in \a this number of cells with this geo type.
+ * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated.
+ * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
+ *
+ * \sa getDistributionOfTypes
+ */
+std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
+{
+  std::vector< std::pair<int,int> > ret;
+  std::vector<int> nel(getNonEmptyLevels());
+  for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
+    {
+      std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
+      for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
+        {
+          int nbCells(getNumberOfCellsWithType(*it1));
+          ret.push_back(std::pair<int,int>(*it1,nbCells));
+        }
+    }
+  ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
+  return ret;
+}
+
 /*!
  * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
  * \throw if the reqsuested \a meshDimRelToMax does not exist.
@@ -3704,12 +3752,42 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords)
   if(coords==(DataArrayDouble *)_coords)
     return ;
   coords->checkAllocated();
-  int nbOfTuples=coords->getNumberOfTuples();
+  int nbOfTuples(coords->getNumberOfTuples());
   _coords=coords;
   coords->incrRef();
   _fam_coords=DataArrayInt::New();
   _fam_coords->alloc(nbOfTuples,1);
   _fam_coords->fillWithZero();
+  _num_coords=0; _rev_num_coords=0; _name_coords=0;
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+    if((MEDFileUMeshSplitL1 *)(*it))
+      (*it)->setCoords(coords);
+}
+
+/*!
+ * Change coords without changing anything concerning families and numbering on nodes.
+ */
+void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
+{
+  if(!coords)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
+  if(coords==(DataArrayDouble *)_coords)
+    return ;
+  coords->checkAllocated();
+  int nbOfTuples(coords->getNumberOfTuples());
+  if(_coords.isNull())
+    {
+      _coords=coords;
+      coords->incrRef();
+    }
+  else
+    {
+      int oldNbTuples(_coords->getNumberOfTuples());
+      if(oldNbTuples!=nbOfTuples)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
+      _coords=coords;
+      coords->incrRef();
+    }
   for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
     if((MEDFileUMeshSplitL1 *)(*it))
       (*it)->setCoords(coords);
@@ -3911,7 +3989,10 @@ void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1,
   cellsNotModified=cellsToModifyConn1.retn();
 }
 
-/*!
+/*! Similar to MEDCouplingUMesh::unPolyze():  converts all polygons (if \a this is a 2D mesh) or polyhedrons
+ * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
+ * in this method.
+ *
  * \param [out] oldCode retrieves the distribution of types before the call if true is returned
  * \param [out] newCode etrieves the distribution of types after the call if true is returned
  * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
@@ -4060,6 +4141,108 @@ DataArrayInt *MEDFileUMesh::zipCoords()
   return ret.retn();
 }
 
+/*!
+ * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
+ * The extraction of \a this is specified by the extractDef \a input map.
+ * This map tells for each level of cells, the cells kept in the extraction.
+ * 
+ * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
+ * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
+ */
+DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
+{
+  std::vector<int> levs(getNonEmptyLevels());
+  std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
+  for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+    {
+      if((*it).first>1)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
+      if((*it).second.isNull())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
+      if((*it).first==1)
+        continue;
+      if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+        {
+          std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+      MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+      mPart->computeNodeIdsAlg(fetchedNodes);
+    }
+  return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
+}
+
+/*!
+ * 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
+ */
+MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
+{
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
+  std::vector<int> levs(getNonEmptyLevels());
+  for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+    {
+      if((*it).first>1)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
+      if((*it).second.isNull())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
+      if((*it).first==1)
+        continue;
+      if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+        {
+          std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+      MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+      ret->setMeshAtLevel((*it).first,mPart);
+      const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
+      if(fam)
+        {
+          MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+          ret->setFamilyFieldArr((*it).first,famPart);
+        }
+      if(num)
+        {
+          MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+          ret->setFamilyFieldArr((*it).first,numPart);
+        }
+    }
+  std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
+  if(it2!=extractDef.end())
+    {
+      const DataArrayDouble *coo(ret->getCoords());
+      if(!coo)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
+      MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
+      MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+      ret->setCoords(cooPart);
+      const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
+      if(fam)
+        {
+          MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+          ret->setFamilyFieldArr(1,famPart);
+        }
+      if(num)
+        {
+          MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+          ret->setFamilyFieldArr(1,numPart);
+        }
+      for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
+        {
+          if((*it3).first==1)
+            continue;
+          MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
+          m->renumberNodesInConn(o2nNodes->begin());
+          ret->setMeshAtLevel((*it3).first,m);
+        }
+    }
+  return ret.retn();
+}
+
 /*!
  * This method performs an extrusion along a path defined by \a m1D.
  * \a this is expected to be a mesh with max mesh dimension equal to 2.
@@ -4349,6 +4532,132 @@ MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
   return ret.retn();
 }
 
+/*!
+ * Computes the symmetry of \a this.
+ * \return a new object.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
+{
+  MCAuto<MEDFileUMesh> ret(deepCopy());
+  DataArrayDouble *myCoo(getCoords());
+  if(myCoo)
+    {
+      MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
+      ret->setCoordsForced(newCoo);
+    }
+  return ret;
+}
+
+MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
+{
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
+  std::size_t sz(meshes.size()),i(0);
+  std::vector<const DataArrayDouble *> coos(sz);
+  std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
+  for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+    {
+      if(!(*it))
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
+      coos[i]=(*it)->getCoords();
+      fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
+      num_coos[i]=(*it)->getNumberFieldAtLevel(1);
+    }
+  const MEDFileUMesh *ref(meshes[0]);
+  int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
+  std::vector<int> levs(ref->getNonEmptyLevels());
+  std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
+  std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
+  std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
+  std::map<std::string,int> map1;
+  std::map<std::string, std::vector<std::string> > map2;
+  for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+    {
+      if((*it)->getSpaceDimension()!=spaceDim)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
+      if((*it)->getMeshDimension()!=meshDim)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
+      if((*it)->getNonEmptyLevels()!=levs)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
+      for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
+        {
+          MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
+          m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
+          m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
+          m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
+        }
+      const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
+      for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
+        map1[(*it3).first]=(*it3).second;
+      const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
+      for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
+        map2[(*it4).first]=(*it4).second;
+    }
+  // Easy part : nodes
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
+  ret->setCoords(coo);
+  if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
+    {
+      MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
+      ret->setFamilyFieldArr(1,fam_coo);
+    }
+  if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
+    {
+      MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
+      ret->setRenumFieldArr(1,num_coo);
+    }
+  // cells
+  for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
+    {
+      std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
+      if(it2==m_mesh.end())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
+      MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
+      mesh->setCoords(coo); mesh->setName(ref->getName());
+      MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
+      ret->setMeshAtLevel(*it,mesh);
+      std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
+      if(it3!=m_fam.end())
+        {
+          const std::vector<const DataArrayInt *>& fams((*it3).second);
+          if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
+            {
+              MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
+              famm->renumberInPlace(renum->begin());
+              ret->setFamilyFieldArr(*it,famm);
+            }
+        }
+      if(it4!=m_renum.end())
+        {
+          const std::vector<const DataArrayInt *>& renums((*it4).second);
+          if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
+            {
+              MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
+              renumm->renumberInPlace(renum->begin());
+              ret->setRenumFieldArr(*it,renumm);
+            }
+        }
+    }
+  //
+  ret->setFamilyInfo(map1);
+  ret->setGroupInfo(map2);
+  ret->setName(ref->getName());
+  return ret;
+}
+
+MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
+{
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
+  MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
+  if(m3D.isNull() || m2D.isNull())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
+  int zeId(getFamilyId(GetSpeStr4ExtMesh()));
+  MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
+  return ret.retn();
+}
+
 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
 {
   clearNonDiscrAttributes();
@@ -5301,22 +5610,25 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI
   {
     case 0:
       {
-        int nbCells=mesh->getNumberOfCells();
-        famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
+        int nbCells(mesh->getNumberOfCells());
+        if(famArr)
+          famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
         _fam_cells=famArr;
         break;
       }
     case 1:
       {
-        int nbNodes=mesh->getNumberOfNodes();
-        famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+        int nbNodes(mesh->getNumberOfNodes());
+        if(famArr)
+          famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
         _fam_nodes=famArr;
         break;
       }
     case -1:
       {
-        int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
-        famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
+        int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
+        if(famArr)
+          famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
         _fam_faces=famArr;
         break;
       }
@@ -6198,7 +6510,7 @@ std::string MEDFileCMesh::advancedRepr() const
   return simpleRepr();
 }
 
-MEDFileMesh *MEDFileCMesh::shallowCpy() const
+MEDFileCMesh *MEDFileCMesh::shallowCpy() const
 {
   MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
   return ret.retn();
@@ -6209,7 +6521,7 @@ MEDFileMesh *MEDFileCMesh::createNewEmpty() const
   return new MEDFileCMesh;
 }
 
-MEDFileMesh *MEDFileCMesh::deepCopy() const
+MEDFileCMesh *MEDFileCMesh::deepCopy() const
 {
   MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
   ret->deepCpyEquivalences(*this);
@@ -6440,7 +6752,7 @@ std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWi
   return ret;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
 {
   MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
   return ret.retn();
@@ -6451,7 +6763,7 @@ MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
   return new MEDFileCurveLinearMesh;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::deepCopy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
 {
   MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
   ret->deepCpyEquivalences(*this);