Salome HOME
Merge from V6_main 12/04/2013
[tools/medcoupling.git] / src / MEDLoader / MEDFileMesh.cxx
index 987e61bd07dd86be49611719a5a66419c9c4e603..6c583f5c43097e38545a04adcfe0d12ae17c9748 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2013  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
@@ -660,9 +660,9 @@ void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName
   const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
   if(fieldFamIds==0)
     throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
-  std::set<int> famIds=fieldFamIds->getDifferentValues();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
   std::vector<std::string> familiesOnWholeGroup;
-  for(std::set<int>::const_iterator it=famIds.begin();it!=famIds.end();it++)
+  for(const int *it=famIds->begin();it!=famIds->end();it++)
     {
       bool tmp;
       familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
@@ -694,9 +694,9 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std
       const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
       if(fieldFamIds)
         {
-          std::set<int> famIds3=fieldFamIds->getDifferentValues();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
           std::vector<int> tmp;
-          std::set_intersection(famIds3.begin(),famIds3.end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
+          std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
           for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
             {
               ret=false;
@@ -940,13 +940,13 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception
       const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
       if(fam)
         {
-          std::set<int> tmp=fam->getDifferentValues();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
           std::set<int> r2;
-          std::set_intersection(tmp.begin(),tmp.end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
+          std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
           if(!r2.empty())
             famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
           std::set<int> r3;
-          std::set_union(tmp.begin(),tmp.end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
+          std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
         }
     }
   if(famIdsToRenum.empty())
@@ -999,15 +999,15 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
       if(fam)
         {
           int refId=1;
-          std::set<int> tmp=fam->getDifferentValues();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
           std::map<int,int> ren;
-          for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++,refId++)
+          for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
             ren[*it]=refId;
           int nbOfTuples=fam->getNumberOfTuples();
           int *start=const_cast<DataArrayInt *>(fam)->getPointer();
           for(int *w=start;w!=start+nbOfTuples;w++)
             *w=ren[*w];
-          for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++)
+          for(const int *it=tmp->begin();it!=tmp->end();it++)
             {
               if(allIds->presenceOfValue(*it))
                 {
@@ -1025,15 +1025,15 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
       if(fam)
         {
           int refId=-1;
-          std::set<int> tmp=fam->getDifferentValues();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
           std::map<int,int> ren;
-          for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++,refId--)
+          for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
             ren[*it]=refId;
           int nbOfTuples=fam->getNumberOfTuples();
           int *start=const_cast<DataArrayInt *>(fam)->getPointer();
           for(int *w=start;w!=start+nbOfTuples;w++)
             *w=ren[*w];
-          for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++)
+          for(const int *it=tmp->begin();it!=tmp->end();it++)
             {
               if(allIds->presenceOfValue(*it))
                 {
@@ -1049,9 +1049,9 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
       DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
       if(fam)
         {
-          std::set<int> tmp=fam->getDifferentValues();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
           fam->fillWithZero();
-          for(std::set<int>::const_iterator it3=tmp.begin();it3!=tmp.end();it3++)
+          for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
             if(allIds->presenceOfValue(*it3))
               {
                 std::string famName=getFamilyNameGivenId(*it3);
@@ -1091,15 +1091,15 @@ void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
       const DataArrayInt *fam=getFamilyFieldAtLevel(1);
       if(fam)
         {
-          std::set<int> tmp=fam->getDifferentValues();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
           std::map<int,int> ren;
-          for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++,refId++)
+          for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
             ren[*it]=refId;
           int nbOfTuples=fam->getNumberOfTuples();
           int *start=const_cast<DataArrayInt *>(fam)->getPointer();
           for(int *w=start;w!=start+nbOfTuples;w++)
             *w=ren[*w];
-          for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++)
+          for(const int *it=tmp->begin();it!=tmp->end();it++)
             {
               if(allIds->presenceOfValue(*it))
                 {
@@ -1116,15 +1116,15 @@ void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
       const DataArrayInt *fam=getFamilyFieldAtLevel(1);
       if(fam)
         {
-          std::set<int> tmp=fam->getDifferentValues();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
           std::map<int,int> ren;
-          for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++,refId--)
+          for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
             ren[*it]=refId;
           int nbOfTuples=fam->getNumberOfTuples();
           int *start=const_cast<DataArrayInt *>(fam)->getPointer();
           for(int *w=start;w!=start+nbOfTuples;w++)
             *w=ren[*w];
-          for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++)
+          for(const int *it=tmp->begin();it!=tmp->end();it++)
             {
               if(allIds->presenceOfValue(*it))
                 {
@@ -1257,7 +1257,7 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<con
   if(!_families.empty())
     offset=getMaxFamilyId()+1;
   TranslateFamilyIds(offset,fam,fidsOfGroups);
-  std::set<int> ids=fam->getDifferentValues();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
   appendFamilyEntries(ids,fidsOfGroups,grpsName2);
   setFamilyFieldArr(meshDimRelToMaxExt,fam);
 }
@@ -1267,10 +1267,10 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<con
  * not in '_families'. Groups information are given in parameters in order to give to families representative names.
  * For the moment, the two last input parameters are not taken into account.
  */
-void MEDFileMesh::appendFamilyEntries(const std::set<int>& famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
+void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
 {
   std::map<int,std::string> famInv;
-  for(std::set<int>::const_iterator it=famIds.begin();it!=famIds.end();it++)
+  for(const int *it=famIds->begin();it!=famIds->end();it++)
     {
       std::ostringstream oss;
       oss << "Family_" << (*it);
@@ -1439,6 +1439,8 @@ std::size_t MEDFileUMesh::getHeapMemorySize() const
     ret+=_num_coords->getHeapMemorySize();
   if((const DataArrayInt *)_rev_num_coords)
     ret+=_rev_num_coords->getHeapMemorySize();
+  if((const DataArrayAsciiChar *)_name_coords)
+    ret+=_name_coords->getHeapMemorySize();
   ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     if((const MEDFileUMeshSplitL1*) *it)
@@ -1463,6 +1465,8 @@ MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
     ret->_num_coords=_num_coords->deepCpy();
   if((const DataArrayInt*)_rev_num_coords)
     ret->_rev_num_coords=_rev_num_coords->deepCpy();
+  if((const DataArrayAsciiChar*)_name_coords)
+    ret->_name_coords=_name_coords->deepCpy();
   std::size_t i=0;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
     {
@@ -1532,6 +1536,22 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh
           return false;
         }
     }
+  const DataArrayAsciiChar *namec1=_name_coords;
+  const DataArrayAsciiChar *namec2=otherC->_name_coords;
+  if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
+    {
+      what="Mismatch of naming arr on nodes ! One is defined and not other !";
+      return false;
+    }
+  if(namec1)
+    {
+      bool ret=namec1->isEqual(*namec2);
+      if(!ret)
+        {
+          what="Names arr on node differ !";
+          return false;
+        }
+    }
   if(_ms.size()!=otherC->_ms.size())
     {
       what="Number of levels differs !";
@@ -1569,6 +1589,9 @@ void MEDFileUMesh::clearNonDiscrAttributes() const
   const DataArrayInt *numc1=_num_coords;
   if(numc1)
     (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
+  const DataArrayAsciiChar *namc1=_name_coords;
+  if(namc1)
+    (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     {
       const MEDFileUMeshSplitL1 *tmp=(*it);
@@ -1624,6 +1647,7 @@ void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int
   _coords=loaderl2.getCoords();
   _fam_coords=loaderl2.getCoordsFamily();
   _num_coords=loaderl2.getCoordsNum();
+  _name_coords=loaderl2.getCoordsName();
   computeRevNum();
 }
 
@@ -1651,7 +1675,7 @@ void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
       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
     }
   MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
-  MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords);
+  MEDFileUMeshL2::WriteCoords(fid,maa,_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,maa,mdim);
@@ -1934,6 +1958,14 @@ const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt)
   return l1->getNumberField();
 }
 
+const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt==1)
+    return _name_coords;
+  const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
+  return l1->getNameField();
+}
+
 int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
 {
   const DataArrayDouble *coo=_coords;
@@ -2041,7 +2073,10 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve
 }
 
 /*!
- * Returns a pointer to mesh at the specified level.
+ * Returns a pointer to mesh at the specified level. ** WARNING **, if the input \a meshDimRelToMaxExt is set to one (nodes),
+ * The returned mesh ** will be not valid **. It is a feature, because MEDLoader do not creates cells that do not exist !
+ * To build a valid MEDCouplingUMesh instance from the returned value when \a meshDimRelToMaxExt is equal to one, simply
+ * call MEDCouplingUMesh::Build0DMeshFromCoords.
  * 
  * \return a pointer to unstructured mesh that need to be managed by the caller.
  * \warning the returned pointer has to be managed by the caller.
@@ -2175,9 +2210,9 @@ void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
     {
       const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
-      std::set<int> ids=ffield->getDifferentValues();
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
       std::set<int> res;
-      std::set_union(ids.begin(),ids.end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
+      std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
       allFamsIds=res;
     }
   std::set<std::string> famNamesToKill;
@@ -2405,12 +2440,15 @@ DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
   if((const DataArrayInt *)_fam_coords)
     newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
   if((const DataArrayInt *)_num_coords)
     newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
-  _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _rev_num_coords=0;
+  if((const DataArrayAsciiChar *)_name_coords)
+    newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
+  _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
     {
       if((MEDFileUMeshSplitL1*)*it)
@@ -2474,7 +2512,7 @@ void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *fa
   std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
   allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
-  std::set<int> diffFamIds=famIds->getDifferentValues();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
   std::vector<int> familyIds;
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
   int maxVal=getTheMaxFamilyId()+1;
@@ -2482,7 +2520,7 @@ void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *fa
   std::map<std::string, std::vector<std::string> > groups(_groups);
   std::vector<std::string> fams;
   bool created(false);
-  for(std::set<int>::const_iterator famId=diffFamIds.begin();famId!=diffFamIds.end();famId++)
+  for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
     {
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
@@ -2708,6 +2746,33 @@ void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumA
   return _ms[traducedRk]->setRenumArr(renumArr);
 }
 
+void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt==1)
+    {
+      if(!nameArr)
+        {
+          _name_coords=0;
+          return ;
+        }
+      DataArrayDouble *coo(_coords);
+      if(!coo)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
+      nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
+      nameArr->incrRef();
+      _name_coords=nameArr;
+      return ;
+    }
+  if(meshDimRelToMaxExt>1)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
+  int traducedRk=-meshDimRelToMaxExt;
+  if(traducedRk>=(int)_ms.size())
+    throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
+  if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
+    throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
+  return _ms[traducedRk]->setNameArr(nameArr);
+}
+
 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
 {
   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
@@ -2886,6 +2951,38 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s
           return false;
         }
     }
+  const DataArrayAsciiChar *d1=_names_cells;
+  const DataArrayAsciiChar *d2=otherC->_names_cells;
+  if((d1==0 && d2!=0) || (d1!=0 && d2==0))
+    {
+      what="Mismatch of naming arr on cells ! One is defined and not other !";
+      return false;
+    }
+  if(d1)
+    {
+      bool ret=d1->isEqual(*d2);
+      if(!ret)
+        {
+          what="Naming arr on cells differ !";
+          return false;
+        }
+    }
+  d1=_names_nodes;
+  d2=otherC->_names_nodes;
+  if((d1==0 && d2!=0) || (d1!=0 && d2==0))
+    {
+      what="Mismatch of naming arr on nodes ! One is defined and not other !";
+      return false;
+    }
+  if(d1)
+    {
+      bool ret=d1->isEqual(*d2);
+      if(!ret)
+        {
+          what="Naming arr on nodes differ !";
+          return false;
+        }
+    }
   return true;
 }
 
@@ -2957,13 +3054,13 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI
   if(meshDimRelToMaxExt==0)
     {
       int nbCells=mesh->getNumberOfCells();
-      famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
+      famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
       _fam_cells=famArr;
     }
   else
     {
       int nbNodes=mesh->getNumberOfNodes();
-      famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+      famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
       _fam_nodes=famArr;
     }
   if(famArr)
@@ -2986,13 +3083,36 @@ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIn
   else
     {
       int nbNodes=mesh->getNumberOfNodes();
-      renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+      renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
       _num_nodes=renumArr;
     }
   if(renumArr)
     renumArr->incrRef();
 }
 
+void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
+  const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
+  if(!mesh)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
+  if(meshDimRelToMaxExt==0)
+    {
+      int nbCells=mesh->getNumberOfCells();
+      nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
+      _names_cells=nameArr;
+    }
+  else
+    {
+      int nbNodes=mesh->getNumberOfNodes();
+      nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
+      _names_nodes=nameArr;
+    }
+  if(nameArr)
+    nameArr->incrRef();
+}
+
 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
 {
   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
@@ -3043,6 +3163,16 @@ const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimR
     }
 }
 
+const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
+{
+  if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
+  if(meshDimRelToMaxExt==0)
+    return _names_cells;
+  else
+    return _names_nodes;
+}
+
 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
 {
   std::vector<int> ret(1);
@@ -3193,6 +3323,22 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt
       _num_cells->alloc(nbOfElt,1);
       MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
     }
+  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
+  if(nbOfElt>0)
+    {
+      _names_cells=DataArrayAsciiChar::New();
+      _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
+      MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
+      _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
+    }
+  nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
+  if(nbOfElt>0)
+    {
+      _names_nodes=DataArrayAsciiChar::New();
+      _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
+      MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
+      _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
+    }
 }
 
 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
@@ -3208,6 +3354,26 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) cons
     MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
   if((const DataArrayInt *)_num_nodes)
     MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
+  if((const DataArrayAsciiChar *)_names_cells)
+    {
+      if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
+        {
+          std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
+          oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
+    }
+  if((const DataArrayAsciiChar *)_names_nodes)
+    {
+      if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
+        {
+          std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
+          oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
+    }
   //
   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
 }