Salome HOME
Encourage users at most to use cartesian.
[tools/medcoupling.git] / src / MEDLoader / MEDFileMesh.cxx
index 9c7698caf9fa2411a8792decd3037be4adc5cf42..0e1b5a32160cf08c82beb8effe9c9e4c3e593289 100644 (file)
@@ -39,7 +39,7 @@ using namespace ParaMEDMEM;
 
 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
 
-MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
+MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
 {
 }
 
@@ -59,7 +59,9 @@ std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
 
 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
 {
-  return std::vector<const BigMemoryObject *>();
+  std::vector<const BigMemoryObject *> ret(1);
+  ret[0]=(const MEDFileEquivalences *)_equiv;
+  return ret;
 }
 
 /*!
@@ -85,29 +87,25 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  ParaMEDMEM::MEDCouplingAxisType dummy3;
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ret;
   switch(meshType)
   {
     case UNSTRUCTURED:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
-        ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileUMesh *)ret.retn();
+        ret=MEDFileUMesh::New();
+        break;
       }
     case CARTESIAN:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
-        ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileCMesh *)ret.retn();
+        ret=MEDFileCMesh::New();
+        break;
       }
     case CURVE_LINEAR:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
-        ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileCurveLinearMesh *)ret.retn();
+        ret=MEDFileCurveLinearMesh::New();
+        break;
       }
     default:
       {
@@ -115,6 +113,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   }
+  ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
+  return ret.retn();
 }
 
 /*!
@@ -141,29 +141,25 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN
   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dummy0,dummy1;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
+  ParaMEDMEM::MEDCouplingAxisType dummy3;
+  MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ret;
   switch(meshType)
   {
     case UNSTRUCTURED:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
-        ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileUMesh *)ret.retn();
+        ret=MEDFileUMesh::New();
+        break;
       }
     case CARTESIAN:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
-        ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileCMesh *)ret.retn();
+        ret=MEDFileCMesh::New();
+        break;
       }
     case CURVE_LINEAR:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
-        ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileCurveLinearMesh *)ret.retn();
+        ret=MEDFileCurveLinearMesh::New();
+        break;
       }
     default:
       {
@@ -171,6 +167,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   }
+  ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
+  return ret.retn();
 }
 
 /*!
@@ -187,6 +185,10 @@ void MEDFileMesh::write(med_idt fid) const
   if(_name.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
   writeLL(fid);
+  writeJoints(fid);
+  const MEDFileEquivalences *eqs(_equiv);
+  if(eqs)
+    eqs->write(fid);
 }
 
 /*!
@@ -252,6 +254,8 @@ bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wha
     return false;
   if(!areFamsEqual(other,what))
     return false;
+  if(!areEquivalencesEqual(other,what))
+    return false;
   return true;
 }
 
@@ -511,6 +515,24 @@ std::vector<std::string> MEDFileMesh::getFamiliesNames() const
   return ret;
 }
 
+/*!
+ * Returns names of all families of \a this mesh but like they would be in file.
+ * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
+ * This method is only useful for aggressive users that want to have in their file a same family lying both on cells and on nodes. This is not a good idea for lisibility !
+ * For your information internaly in memory such families are renamed to have a nicer API.
+ */
+std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
+{
+  std::vector<std::string> ret(getFamiliesNames());
+  MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
+  return ret;
+}
+
+std::string MEDFileMesh::GetMagicFamilyStr()
+{
+  return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
+}
+
 /*!
  * Changes a name of every family, included in one group only, to be same as the group name.
  *  \throw If there are families with equal names in \a this mesh.
@@ -1983,10 +2005,17 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() con
 
 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
   return mLev->getDistributionOfTypes();
 }
 
+void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  loadLL(fid,mName,dt,it,mrs);
+  loadJointsFromFile(fid);
+  loadEquivalences(fid);
+}
+
 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
 {
   famArr->applyLin(offset>0?1:-1,offset,0);
@@ -2149,7 +2178,8 @@ MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSele
   int dt,it;
   ParaMEDMEM::MEDCouplingMeshType meshType;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  ParaMEDMEM::MEDCouplingAxisType dummy3;
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
   return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
 }
 
@@ -2220,7 +2250,7 @@ std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() c
 
 MEDFileMesh *MEDFileUMesh::shallowCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
   return ret.retn();
 }
 
@@ -2231,7 +2261,8 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const
 
 MEDFileMesh *MEDFileUMesh::deepCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
+  ret->deepCpyEquivalences(*this);
   if((const DataArrayDouble*)_coords)
     ret->_coords=_coords->deepCpy();
   if((const DataArrayInt*)_fam_coords)
@@ -2410,9 +2441,8 @@ MEDFileUMesh::MEDFileUMesh()
 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadUMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
-  }
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
+}
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
@@ -2422,7 +2452,7 @@ catch(INTERP_KERNEL::Exception& e)
  * This method loads only a part of specified cells (given by range of cell ID per geometric type)
  * See MEDFileUMesh::LoadPartOf for detailed description.
  *
- * \sa loadUMeshFromFile
+ * \sa loadLL
  */
 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
@@ -2430,7 +2460,8 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName,
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dummy2;
-  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
+  ParaMEDMEM::MEDCouplingAxisType dummy3;
+  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
   if(meshType!=UNSTRUCTURED)
     {
       std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
@@ -2470,12 +2501,61 @@ void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfRe
     _joints = MEDFileJoints::New( fid, _name );
 }
 
+void MEDFileMesh::loadEquivalences(med_idt fid)
+{
+  int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
+  if(nbOfEq>0)
+    _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
+}
+
+void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
+{
+  const MEDFileEquivalences *equiv(other._equiv);
+  if(equiv)
+    _equiv=equiv->deepCpy(this);
+}
+
+bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
+{
+  const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
+  if(!thisEq && !otherEq)
+    return true;
+  if(thisEq && otherEq)
+    return thisEq->isEqual(otherEq,what);
+  else
+    {
+      what+="Equivalence differs : defined in this and not in other (or reversely) !";
+      return false;
+    }
+}
+
+void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
+{
+  const MEDFileEquivalences *equiv(_equiv);
+  if(!equiv)
+    return ;
+  oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
+  _equiv->getRepr(oss);
+}
+
+void MEDFileMesh::checkCartesian() const
+{
+  if(getAxType()!=AX_CART)
+    {
+      std::ostringstream oss; oss << "MEDFileMesh::checkCartesian : request for method that is dedicated to a cartesian convention ! But you are not in cartesian convention (" << DataArray::GetAxTypeRepr(getAxType()) << ").";
+      oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
+      oss << " - call setAxType(AX_CART)" << std::endl;
+      oss << " - call cartesianize()";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
 /*!
  * \brief Return number of joints, which is equal to number of adjacent mesh domains
  */
-int MEDFileMesh::getNumberOfJoints()
+int MEDFileMesh::getNumberOfJoints() const
 {
-  return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0;
+  return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
 }
 
 /*!
@@ -2501,13 +2581,15 @@ void MEDFileMesh::setJoints( MEDFileJoints* joints )
  *
  * \sa loadPartUMeshFromFile
  */
-void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUMeshL2 loaderl2;
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dummy2;
-  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
+  ParaMEDMEM::MEDCouplingAxisType axType;
+  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
+  setAxType(axType);
   if(meshType!=UNSTRUCTURED)
     {
       std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
@@ -2573,16 +2655,15 @@ void MEDFileUMesh::writeLL(med_idt fid) const
       MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
       MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
-  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
-  MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
+  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),comp,unit));
+  if(_univ_wr_status)
+    MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
   std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
   MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
       (*it)->write(fid,meshName,mdim);
   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
-
-  writeJoints(fid);
 }
 
 /*!
@@ -2942,6 +3023,7 @@ std::string MEDFileUMesh::simpleRepr() const
     }
   oss << std::endl << std::endl;
   getFamilyRepr(oss);
+  getEquivalencesRepr(oss);
   return oss.str();
 }
 
@@ -3076,6 +3158,29 @@ void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, con
     }
 }
 
+MEDFileMesh *MEDFileUMesh::cartesianize() const
+{
+  if(getAxType()==AX_CART)
+    {
+      incrRef();
+      return const_cast<MEDFileUMesh *>(this);
+    }
+  else
+    {
+      MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
+      const DataArrayDouble *coords(_coords);
+      if(!coords)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsCart(_coords->cartesianize(getAxType()));
+      for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
+        if((const MEDFileUMeshSplitL1 *)(*it))
+          *it=(*it)->shallowCpyUsingCoords(coordsCart);
+      ret->_coords=coordsCart;
+      ret->setAxType(AX_CART);
+      return ret.retn();
+    }
+}
+
 /*!
  * Returns the optional numbers of mesh entities of a given dimension transformed using
  * DataArrayInt::invertArrayN2O2O2N().
@@ -3102,6 +3207,7 @@ const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxEx
  */
 DataArrayDouble *MEDFileUMesh::getCoords() const
 {
+  checkCartesian();
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
   if((DataArrayDouble *)tmp)
     {
@@ -3126,6 +3232,7 @@ DataArrayDouble *MEDFileUMesh::getCoords() const
  */
 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> tmp(1);
   tmp[0]=grp;
@@ -3148,6 +3255,7 @@ MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::stri
  */
 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> fams2=getFamiliesOnGroups(grps);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
@@ -3172,6 +3280,7 @@ MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vec
  */
 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> tmp(1);
   tmp[0]=fam;
@@ -3194,6 +3303,7 @@ MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::str
  */
 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   if(meshDimRelToMaxExt==1)
     {
@@ -3266,10 +3376,10 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve
  *  \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
  *          delete using decrRef() as it is no more needed. 
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
- * \sa getGenMeshAtLevel()
  */
 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   if(meshDimRelToMaxExt==1)
     {
@@ -3287,25 +3397,6 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu
   return l1->getWholeMesh(renum);
 }
 
-/*!
- * Returns a MEDCouplingUMesh of a given relative dimension.
- * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
- * valid**. This is a feature, because MEDLoader does not create cells that do not exist! 
- * To build a valid MEDCouplingUMesh from the returned one in this case,
- * call MEDCouplingUMesh::Build0DMeshFromCoords().
- *  \param [in] meshDimRelToMax - the relative dimension of interest.
- *  \param [in] renum - if \c true, the returned mesh is permuted according to the
- *          optional numbers of mesh entities.
- *  \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
- *          delete using decrRef() as it is no more needed. 
- *  \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
- * \sa getMeshAtLevel()
- */
-MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
-{
-  return getMeshAtLevel(meshDimRelToMax,renum);
-}
-
 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
 {
   const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
@@ -3388,6 +3479,7 @@ void MEDFileUMesh::forceComputationOfParts() const
  */
 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
 {
+  checkCartesian();
   const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
   return sp->getDirectUndergroundSingleGeoTypeMeshes();
 }
@@ -3399,7 +3491,8 @@ std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTy
  */
 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
 {
-  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
+  checkCartesian();
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
   int lev=(int)cm.getDimension()-getMeshDimension();
   const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
   return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
@@ -3415,6 +3508,13 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(
   return sp->getGeoTypes();
 }
 
+int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
+  const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
+  return sp->getNumberOfCellsWithType(ct);
+}
+
 /*!
  * This method extracts from whole family field ids the part relative to the input parameter \a gt.
  * \param [in] gt - the geometric type for which the family field is asked.
@@ -3510,6 +3610,8 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords)
 {
   if(!coords)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
+  if(coords==(DataArrayDouble *)_coords)
+    return ;
   coords->checkAllocated();
   int nbOfTuples=coords->getNumberOfTuples();
   _coords=coords;
@@ -3583,28 +3685,28 @@ void MEDFileUMesh::optimizeFamilies()
 
 /**
  * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
- * of the top level. This method build a "crack" in \b this along the group of level -1 named grpNameM1.
- * The "crack" is built according to the following method:
- *  - all nodes along the crack which are not lying on an internal extremity of the crack are duplicated (so the
- * coordinates array is extended). The
- *  - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the crack are duplicated.
- *  After this operation a top-level cell bordering the crack will loose some neighbor (typically the cell which is  on the
- *  other side of the crack is no more a neighbor)
- *   - finally, the connectivity of (part of) the top level-cells bordering the crack is also modified so that some cells
- *  bordering the crack use the newly computed nodes.
+ * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
+ * The boundary is built according to the following method:
+ *  - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
+ * coordinates array is extended).
+ *  - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated.
+ *  After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is  on the
+ *  other side of the group is no more a neighbor)
+ *   - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
+ *  bordering the newly created boundary use the newly computed nodes.
  *
- *  \param[in] grpNameM1 name of the (-1)-level group defining the crack
+ *  \param[in] grpNameM1 name of the (-1)-level group defining the boundary
  *  \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
  *  the coord array)
  *  \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
- *  \param[out] cellsNotModified ids of the rest of cells bordering the crack whose connectivity remains unchanged.
+ *  \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
  */
-void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
+void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
                                            DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
 {
   std::vector<int> levs=getNonEmptyLevels();
   if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
-    throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
   int nbNodes=m0->getNumberOfNodes();
@@ -3647,10 +3749,16 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArr
   newm1->setName(getName());
   const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
   if(!fam)
-    throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !");
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
   newFam->alloc(newm1->getNumberOfCells(),1);
-  int idd=getMaxFamilyId()+1;
+  // Get a new family ID: care must be taken if we need a positive ID or a negative one:
+  // Positive ID for family of nodes, negative for all the rest.
+  int idd;
+  if (m1->getMeshDimension() == 0)
+    idd=getMaxFamilyId()+1;
+  else
+    idd=getMinFamilyId()-1;
   int globStart=0,start=0,end,globEnd;
   int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
   for(int i=0;i<nbOfChunks;i++)
@@ -3760,12 +3868,14 @@ bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode
   return ret;
 }
 
+/*! \cond HIDDEN_ITEMS */
 struct MEDLoaderAccVisit1
 {
   MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
   int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
   int _new_nb_of_nodes;
 };
+/*! \endcond */
 
 /*!
  * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
@@ -3853,6 +3963,7 @@ DataArrayInt *MEDFileUMesh::zipCoords()
  */
 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
 {
+  checkCartesian();
   if(getMeshDimension()!=2)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
@@ -3997,6 +4108,7 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
  */
 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
 {
+  checkCartesian();
   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
   int initialNbNodes(getNumberOfNodes());
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
@@ -4029,23 +4141,26 @@ MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) co
         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)
+      if(m1->getMeshDimension()!=0)
         {
-          std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
+          {
+            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
+          }//kill unused notUsed var
+          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());
         }
-      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);
@@ -4070,6 +4185,7 @@ MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) co
  */
 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
 {
+  checkCartesian();
   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
@@ -4126,21 +4242,22 @@ void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>&
   forceComputationOfParts();
   tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
   std::vector<int> layer0;
-  layer0.push_back(_order); //0 i
-  layer0.push_back(_iteration);//1 i
-  layer0.push_back(getSpaceDimension());//2 i
+  layer0.push_back(getAxType());//0 i
+  layer0.push_back(_order); //1 i
+  layer0.push_back(_iteration);//2 i
+  layer0.push_back(getSpaceDimension());//3 i
   tinyDouble.push_back(_time);//0 d
   tinyStr.push_back(_name);//0 s
   tinyStr.push_back(_desc_name);//1 s
   for(int i=0;i<getSpaceDimension();i++)
     tinyStr.push_back(_coords->getInfoOnComponent(i));
-  layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
+  layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       tinyStr.push_back((*it).first);
       layer0.push_back((*it).second);
     }
-  layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
+  layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
   for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
     {
       layer0.push_back((int)(*it0).second.size());
@@ -4148,7 +4265,7 @@ void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>&
       for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
         tinyStr.push_back(*it1);
     }
-  // sizeof(layer0)==3+aa+1+bb layer#0
+  // sizeof(layer0)==4+aa+1+bb layer#0
   bigArrayD=_coords;// 0 bd
   bigArraysI.push_back(_fam_coords);// 0 bi
   bigArraysI.push_back(_num_coords);// 1 bi
@@ -4193,6 +4310,7 @@ void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>
   std::reverse(tinyStr.begin(),tinyStr.end());
   std::reverse(bigArraysI.begin(),bigArraysI.end());
   //
+  setAxType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
   _order=layer0.back(); layer0.pop_back();
   _iteration=layer0.back(); layer0.pop_back();
   int spaceDim(layer0.back()); layer0.pop_back();
@@ -5487,8 +5605,9 @@ void MEDFileStructuredMesh::deepCpyAttributes()
  *  \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
  *          delete using decrRef() as it is no more needed. 
  */
-MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
+MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
 {
+  checkCartesian();
   if(renum)
     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
   const MEDCouplingStructuredMesh *m(getStructuredMesh());
@@ -5503,9 +5622,9 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b
     case -1:
       {
         if(!m)
-          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
+          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
         buildMinusOneImplicitPartIfNeeded();
-        MEDCouplingMesh *ret(_faces_if_necessary);
+        MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
         if(ret)
           ret->incrRef();
         return ret;
@@ -5619,6 +5738,7 @@ void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
  */
 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
 {
+  checkCartesian();
   return _faces_if_necessary;
 }
 
@@ -5647,6 +5767,14 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoType
   }
 }
 
+int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
+{
+  if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
+    return 0;
+  else
+    return getNumberOfCellsAtLevel(0);
+}
+
 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
 {
   if(st.getNumberOfItems()!=1)
@@ -5857,7 +5985,8 @@ MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSele
   int dt,it;
   ParaMEDMEM::MEDCouplingMeshType meshType;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  ParaMEDMEM::MEDCouplingAxisType dummy3;
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
   return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
 }
 
@@ -5938,7 +6067,7 @@ std::string MEDFileCMesh::advancedRepr() const
 
 MEDFileMesh *MEDFileCMesh::shallowCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret(new MEDFileCMesh(*this));
   return ret.retn();
 }
 
@@ -5949,7 +6078,8 @@ MEDFileMesh *MEDFileCMesh::createNewEmpty() const
 
 MEDFileMesh *MEDFileCMesh::deepCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret(new MEDFileCMesh(*this));
+  ret->deepCpyEquivalences(*this);
   if((const MEDCouplingCMesh*)_cmesh)
     ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
   ret->deepCpyAttributes();
@@ -6010,20 +6140,20 @@ MEDFileCMesh::MEDFileCMesh()
 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadCMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
 }
 
-void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dtunit;
-  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
+  ParaMEDMEM::MEDCouplingAxisType axType;
+  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
   if(meshType!=CARTESIAN)
     {
       std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
@@ -6031,6 +6161,7 @@ void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int
     }
   MEDFileCMeshL2 loaderl2;
   loaderl2.loadAll(fid,mid,mName,dt,it);
+  setAxType(loaderl2.getAxType());
   MEDCouplingCMesh *mesh=loaderl2.getMesh();
   mesh->incrRef();
   _cmesh=mesh;
@@ -6067,6 +6198,29 @@ void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
   _cmesh=m;
 }
 
+MEDFileMesh *MEDFileCMesh::cartesianize() const
+{
+  if(getAxType()==AX_CART)
+    {
+      incrRef();
+      return const_cast<MEDFileCMesh *>(this);
+    }
+  else
+    {
+      const MEDCouplingCMesh *cmesh(getMesh());
+      if(!cmesh)
+        throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxType()));
+      clmesh->setCoords(coords);
+      MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
+      ret->MEDFileStructuredMesh::operator=(*this);
+      ret->setMesh(clmesh);
+      ret->setAxType(AX_CART);
+      return ret.retn();
+    }
+}
+
 void MEDFileCMesh::writeLL(med_idt fid) const
 {
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
@@ -6086,9 +6240,11 @@ void MEDFileCMesh::writeLL(med_idt fid) const
       MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
       MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
+  // MED_CARTESIAN and not MEDFileMeshL2::TraduceAxisTypeRev(getAxType()) ! Yes it is not a bug. The discrimination is done in MEDmeshGridTypeWr.
   MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
-  MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
-  MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID));
+  if(_univ_wr_status)
+    MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
+  MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxType())));
   for(int i=0;i<spaceDim;i++)
     {
       const DataArrayDouble *da=_cmesh->getCoordsAt(i);
@@ -6097,8 +6253,6 @@ void MEDFileCMesh::writeLL(med_idt fid) const
   //
   std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
   MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
-
-  writeJoints(fid);
 }
 
 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
@@ -6129,8 +6283,9 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName,
   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
   ParaMEDMEM::MEDCouplingMeshType meshType;
+  ParaMEDMEM::MEDCouplingAxisType dummy3;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
   return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
 }
 
@@ -6155,7 +6310,7 @@ std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWi
 
 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
   return ret.retn();
 }
 
@@ -6166,7 +6321,8 @@ MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
 
 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
+  MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
+  ret->deepCpyEquivalences(*this);
   if((const MEDCouplingCurveLinearMesh*)_clmesh)
     ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
   ret->deepCpyAttributes();
@@ -6252,6 +6408,31 @@ void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
   _clmesh=m;
 }
 
+MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
+{
+  if(getAxType()==AX_CART)
+    {
+      incrRef();
+      return const_cast<MEDFileCurveLinearMesh *>(this);
+    }
+  else
+    {
+      const MEDCouplingCurveLinearMesh *mesh(getMesh());
+      if(!mesh)
+        throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
+      const DataArrayDouble *coords(mesh->getCoords());
+      if(!coords)
+        throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
+      MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsCart(coords->cartesianize(getAxType()));
+      mesh2->setCoords(coordsCart);
+      ret->setMesh(mesh2);
+      ret->setAxType(AX_CART);
+      return ret.retn();
+    }
+}
+
 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
 {
   synchronizeTinyInfoOnLeaves();
@@ -6265,8 +6446,7 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadCLMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
@@ -6296,8 +6476,9 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
       MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
       MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
-  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
-  MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
+  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),comp,unit));
+  if(_univ_wr_status)
+    MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
   MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
   std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
   MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
@@ -6306,16 +6487,16 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
   //
   std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
   MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
-
-  writeJoints(fid);
 }
 
-void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dtunit;
-  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
+  ParaMEDMEM::MEDCouplingAxisType axType;
+  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
+  setAxType(axType);
   if(meshType!=CURVE_LINEAR)
     {
       std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
@@ -6396,6 +6577,19 @@ bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,st
   return ret;
 }
 
+void MEDFileMeshMultiTS::cartesianizeMe()
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+    {
+      MEDFileMesh *cur(*it);
+      if(cur)
+        {
+          MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
+          *it=ccur;
+        }
+    }
+}
+
 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
 {
   if(_mesh_one_ts.empty())
@@ -6490,7 +6684,8 @@ try
     int dt,it;
     ParaMEDMEM::MEDCouplingMeshType meshType;
     std::string dummy2;
-    MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+    ParaMEDMEM::MEDCouplingAxisType dummy3;
+    MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
     loadFromFile(fileName,ms.front());
 }
 catch(INTERP_KERNEL::Exception& e)
@@ -6592,16 +6787,6 @@ std::vector<std::string> MEDFileMeshes::getMeshesNames() const
     }
   return ret;
 }
-/*const MEDFileJoints* MEDFileMeshes::getJoints() const
-{
-  const MEDFileJoints *ret=_joints;
-  if(!ret)
-  {
-    std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !";
-    throw INTERP_KERNEL::Exception(oss.str().c_str());
-  }
-  return ret;
-}*/
 
 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
 {
@@ -6615,6 +6800,16 @@ bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::st
   return ret;
 }
 
+void MEDFileMeshes::cartesianizeMe()
+{
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
+    {
+      MEDFileMeshMultiTS *cur(*it);
+      if(cur)
+        cur->cartesianizeMe();
+    }
+}
+
 void MEDFileMeshes::resize(int newSize)
 {
   _meshes.resize(newSize);