Salome HOME
987e61bd07dd86be49611719a5a66419c9c4e603
[modules/med.git] / src / MEDLoader / MEDFileMesh.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileUtilities.hxx"
23 #include "MEDLoader.hxx"
24 #include "MEDLoaderBase.hxx"
25
26 #include "MEDCouplingUMesh.hxx"
27
28 #include "InterpKernelAutoPtr.hxx"
29
30 #include <limits>
31 #include <cmath>
32
33 using namespace ParaMEDMEM;
34
35 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
36
37 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.)
38 {
39 }
40
41 std::size_t MEDFileMesh::getHeapMemorySize() const
42 {
43   std::size_t ret=_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity();
44   for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
45     {
46       ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
47       for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
48         ret+=(*it2).capacity();
49     }
50   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
51     ret+=(*it).first.capacity()+sizeof(int);
52   return ret;
53 }
54
55 MEDFileMesh *MEDFileMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
56 {
57   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
58   if(ms.empty())
59     {
60       std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
61       throw INTERP_KERNEL::Exception(oss.str().c_str());
62     }
63   MEDFileUtilities::CheckFileForRead(fileName);
64   ParaMEDMEM::MEDCouplingMeshType meshType;
65   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
66   int dt,it;
67   std::string dummy2;
68   MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
69   switch(meshType)
70     {
71     case UNSTRUCTURED:
72       {
73         MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
74         ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it);
75         return (MEDFileUMesh *)ret.retn();
76       }
77     case CARTESIAN:
78       {
79         MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
80         ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it);
81         return (MEDFileCMesh *)ret.retn();
82       }
83     case CURVE_LINEAR:
84       {
85         MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
86         ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it);
87         return (MEDFileCMesh *)ret.retn();
88       }
89     default:
90       {
91         std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
92         throw INTERP_KERNEL::Exception(oss.str().c_str());
93       }
94     }
95 }
96
97 MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
98 {
99   MEDFileUtilities::CheckFileForRead(fileName);
100   ParaMEDMEM::MEDCouplingMeshType meshType;
101   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
102   int dummy0,dummy1;
103   std::string dummy2;
104   MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
105   switch(meshType)
106     {
107     case UNSTRUCTURED:
108       {
109         MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
110         ret->loadUMeshFromFile(fid,mName,dt,it);
111         return (MEDFileUMesh *)ret.retn();
112       }
113     case CARTESIAN:
114       {
115         MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
116         ret->loadCMeshFromFile(fid,mName,dt,it);
117         return (MEDFileCMesh *)ret.retn();
118       }
119     default:
120       {
121         std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
122         throw INTERP_KERNEL::Exception(oss.str().c_str());
123       }
124     }
125 }
126
127 void MEDFileMesh::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
128 {
129   if(!existsFamily(0))
130     const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
131   if(_name.empty())
132     throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
133   writeLL(fid);
134 }
135
136 void MEDFileMesh::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
137 {
138   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
139   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
140   std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
141   MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
142   write(fid);
143 }
144
145 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
146 {
147   if(_order!=other->_order)
148     {
149       what="Orders differ !";
150       return false;
151     }
152   if(_iteration!=other->_iteration)
153     {
154       what="Iterations differ !";
155       return false;
156     }
157   if(fabs(_time-other->_time)>eps)
158     {
159       what="Time values differ !";
160       return false;
161     }
162   if(_dt_unit!=other->_dt_unit)
163     {
164       what="Time units differ !";
165       return false;
166     }
167   if(_name!=other->_name)
168     {
169       what="Names differ !";
170       return false;
171     }
172   if(_univ_name!=other->_univ_name)
173     {
174       what="Univ names differ !";
175       return false;
176     }
177   if(_desc_name!=other->_desc_name)
178     {
179       what="Description names differ !";
180       return false;
181     }
182   if(!areGrpsEqual(other,what))
183     return false;
184   if(!areFamsEqual(other,what))
185     return false;
186   return true;
187 }
188
189 void MEDFileMesh::clearNonDiscrAttributes() const
190 {
191   
192 }
193
194 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
195 {
196   for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
197     {
198       if((*it).first==_name)
199         {
200           _name=(*it).second;
201           return true;
202         }
203     }
204   return false;
205 }
206
207 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
208 {
209   _groups=other._groups;
210   _families=other._families;
211 }
212
213 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
214 {
215   std::string oname(name);
216   std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
217   std::vector<std::string> grps=getGroupsNames();
218   if(it==_groups.end())
219     {
220       std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
221       std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
222       throw INTERP_KERNEL::Exception(oss.str().c_str());
223     }
224   return (*it).second;
225 }
226
227 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
228 {
229   std::set<std::string> fams;
230   for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
231     {
232       std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
233       if(it2==_groups.end())
234         {
235           std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; 
236           std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
237           std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
238           throw INTERP_KERNEL::Exception(oss.str().c_str());
239         }
240       fams.insert((*it2).second.begin(),(*it2).second.end());
241     }
242   std::vector<std::string> fams2(fams.begin(),fams.end());
243   return fams2;
244 }
245
246 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
247 {
248   std::string oname(name);
249   std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
250   std::vector<std::string> grps=getGroupsNames();
251   if(it==_groups.end())
252     {
253       std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
254       std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
255       throw INTERP_KERNEL::Exception(oss.str().c_str());
256     }
257   return getFamiliesIds((*it).second);
258 }
259
260 /*!
261  * This method sets families at a corresponding groups existing or not. If it existed, it is replaced by new 'fams'.
262  * Each entry in 'fams' is checked if it is not still existing default id 0 is set.
263  */
264 void MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception)
265 {
266   std::string oname(name);
267   _groups[oname]=fams;
268   for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
269     {
270       std::map<std::string,int>::iterator it2=_families.find(*it1);
271       if(it2==_families.end())
272         _families[*it1]=0;
273     }
274 }
275
276 /*!
277  * Behaves as MEDFileMesh::setFamiliesOnGroup, except that if there is presence of a family id in 'famIds' not existing an exception is thrown.
278  * If several families have same id the first one in lexical order is taken into account.
279  */
280 void MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector<int>& famIds) throw(INTERP_KERNEL::Exception)
281 {
282   std::string oname(name);
283   std::vector<std::string> fams(famIds.size());
284   int i=0;
285   for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
286     {
287       std::string name2=getFamilyNameGivenId(*it1);
288       fams[i]=name2;
289     }
290   _groups[oname]=fams;
291 }
292
293 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception)
294 {
295   std::vector<std::string> ret;
296   for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
297     {
298       for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
299         if((*it2)==name)
300           {
301             ret.push_back((*it1).first);
302             break;
303           }
304     }
305   return ret;
306 }
307
308 /*!
309  * This method expects that family 'famName' is already existing. If not an exception will be thrown.
310  */
311 void MEDFileMesh::setGroupsOnFamily(const char *famName, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception)
312 {
313   std::string fName(famName);
314   const std::map<std::string,int>::const_iterator it=_families.find(fName);
315   if(it==_families.end())
316     {
317       std::vector<std::string> fams=getFamiliesNames();
318       std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
319       std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
320       throw INTERP_KERNEL::Exception(oss.str().c_str());
321     }
322   for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
323     {
324       std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
325       if(it2!=_groups.end())
326         (*it2).second.push_back(fName);
327       else
328         {
329           std::vector<std::string> grps2(1,fName);
330           _groups[*it3]=grps2;
331         }
332     }
333 }
334
335 std::vector<std::string> MEDFileMesh::getGroupsNames() const
336 {
337   std::vector<std::string> ret(_groups.size());
338   int i=0;
339   for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
340     ret[i]=(*it).first;
341   return ret;
342 }
343
344 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
345 {
346   std::vector<std::string> ret(_families.size());
347   int i=0;
348   for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
349     ret[i]=(*it).first;
350   return ret;
351 }
352
353 /*!
354  * This method scans every families and for each families shared by only one group, the corresponding family takes the same name than the group.
355  */
356 void MEDFileMesh::assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception)
357 {
358   std::map<std::string, std::vector<std::string> > groups(_groups);
359   std::map<std::string,int> newFams;
360   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
361     {
362       std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
363       if(grps.size()==1 && groups[grps[0]].size()==1)
364         {
365           if(newFams.find(grps[0])!=newFams.end())
366             {
367               std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
368               throw INTERP_KERNEL::Exception(oss.str().c_str());
369             }
370           newFams[grps[0]]=(*it).second;
371           std::vector<std::string>& grps2=groups[grps[0]];
372           std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
373           grps2[pos]=grps[0];
374         }
375       else
376         {
377           if(newFams.find((*it).first)!=newFams.end())
378             {
379               std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
380               throw INTERP_KERNEL::Exception(oss.str().c_str());
381             }
382           newFams[(*it).first]=(*it).second;
383         }
384     }
385   _families=newFams;
386   _groups=groups;
387 }
388
389 void MEDFileMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception)
390 {
391   std::string oname(name);
392   std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
393   std::vector<std::string> grps=getGroupsNames();
394   if(it==_groups.end())
395     {
396       std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
397       std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
398       throw INTERP_KERNEL::Exception(oss.str().c_str());
399     }
400   _groups.erase(it);
401 }
402
403 void MEDFileMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception)
404 {
405   std::string oname(name);
406   std::map<std::string, int >::iterator it=_families.find(oname);
407   std::vector<std::string> fams=getFamiliesNames();
408   if(it==_families.end())
409     {
410       std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
411       std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
412       throw INTERP_KERNEL::Exception(oss.str().c_str());
413     }
414   _families.erase(it);
415   for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
416     {
417       std::vector<std::string>& v=(*it3).second;
418       std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
419       if(it4!=v.end())
420         v.erase(it4);
421     }
422 }
423
424 void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
425 {
426   std::string oname(oldName);
427   std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
428   std::vector<std::string> grps=getGroupsNames();
429   if(it==_groups.end())
430     {
431       std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
432       std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
433       throw INTERP_KERNEL::Exception(oss.str().c_str());
434     }
435   std::string nname(newName);
436   it=_groups.find(nname);
437   if(it!=_groups.end())
438     {
439       std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
440       throw INTERP_KERNEL::Exception(oss.str().c_str());
441     }
442   std::vector<std::string> cpy=(*it).second;
443   _groups.erase(it);
444   _groups[newName]=cpy;
445 }
446
447 /*!
448  * This method changes the family ids in 'this'. It leads to a modification into '_families' attributes \b and in
449  * ids stored in arrays. This method calls MEDFileMesh::changeFamilyIdArr method.
450  */
451 void MEDFileMesh::changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception)
452 {
453   changeFamilyIdArr(oldId,newId);
454   std::map<std::string,int> fam2;
455   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
456     {
457       if((*it).second==oldId)
458         fam2[(*it).first]=newId;
459       else
460         fam2[(*it).first]=(*it).second;
461     }
462   _families=fam2;
463 }
464
465 void MEDFileMesh::changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
466 {
467   std::string oname(oldName);
468   std::map<std::string, int >::iterator it=_families.find(oname);
469   std::vector<std::string> fams=getFamiliesNames();
470   if(it==_families.end())
471     {
472       std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
473       std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
474       throw INTERP_KERNEL::Exception(oss.str().c_str());
475     }
476   std::string nname(newName);
477   std::map<std::string, int >::iterator it2=_families.find(nname);
478   if(it2!=_families.end())
479     {
480       std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
481       throw INTERP_KERNEL::Exception(oss.str().c_str());
482     }
483   int cpy=(*it).second;
484   _families.erase(it);
485   _families[newName]=cpy;
486   for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
487     {
488       std::vector<std::string>& v=(*it3).second;
489       std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
490       if(it4!=v.end())
491         (*it4)=nname;
492     }
493 }
494
495 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
496 {
497   if(_families==other->_families)
498     return true;
499   std::map<std::string,int> fam0;
500   std::map<std::string,int> fam1;
501   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
502     if((*it).second!=0)
503       fam0[(*it).first]=(*it).second;
504   for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
505     if((*it).second!=0)
506       fam1[(*it).first]=(*it).second;
507   return fam0==fam1;
508 }
509
510 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
511 {
512   if(_groups==other->_groups)
513     return true;
514   bool ret=true;
515   std::size_t sz=_groups.size();
516   if(sz!=other->_groups.size())
517     {
518       what="Groups differ because not same number !\n";
519       ret=false;
520     }
521   if(ret)
522     {
523       std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
524       for(std::size_t i=0;i<sz && ret;i++,it1++)
525         {
526           std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
527           if(it2!=other->_groups.end())
528             {
529               std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
530               std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
531               ret=(s1==s2);
532             }
533           else
534             {
535               ret=false;
536               what="A group in first mesh exists not in other !\n";
537             }
538         }
539     }
540   if(!ret)
541     {
542       std::ostringstream oss; oss << "Groups description differs :\n";
543       oss << "First group description :\n";
544       for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
545         {
546           oss << " Group \"" << (*it).first << "\" on following families :\n";
547           for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
548         oss << "    \"" << *it2 << "\n";
549         }
550       oss << "Second group description :\n";
551       for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
552         {
553           oss << " Group \"" << (*it).first << "\" on following families :\n";
554           for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
555             oss << "    \"" << *it2 << "\n";
556         }
557       what+=oss.str();
558     }
559   return ret;
560 }
561
562 bool MEDFileMesh::existsGroup(const char *groupName) const
563 {
564   std::string grpName(groupName);
565   return _groups.find(grpName)!=_groups.end();
566 }
567
568 bool MEDFileMesh::existsFamily(int famId) const
569 {
570   for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
571     if((*it2).second==famId)
572       return true;
573   return false;
574 }
575
576 bool MEDFileMesh::existsFamily(const char *familyName) const
577 {
578   std::string fname(familyName);
579   return _families.find(fname)!=_families.end();
580 }
581
582 void MEDFileMesh::setFamilyId(const char *familyName, int id)
583 {
584   std::string fname(familyName);
585   _families[fname]=id;
586 }
587
588 void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) throw(INTERP_KERNEL::Exception)
589 {
590   std::string fname(familyName);
591   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
592     if((*it).second==id)
593       {
594         if((*it).first!=familyName)
595           {
596             std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
597             throw INTERP_KERNEL::Exception(oss.str().c_str());
598           }
599       }
600   _families[fname]=id;
601 }
602
603 /*!
604  * This method appends a new entry in _families attribute. An exception is thrown if either the famId is already
605  * kept by an another familyName. An exception is thrown if name 'familyName' is alreadyset with a different 'famId'.
606  */
607 void MEDFileMesh::addFamily(const char *familyName, int famId) throw(INTERP_KERNEL::Exception)
608 {
609   std::string fname(familyName);
610   std::map<std::string,int>::const_iterator it=_families.find(fname);
611   if(it==_families.end())
612     {
613        for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
614          if((*it2).second==famId)
615            {
616              std::ostringstream oss;
617              oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
618              throw INTERP_KERNEL::Exception(oss.str().c_str());
619            }
620        _families[fname]=famId;
621     }
622   else
623     {
624       if((*it).second!=famId)
625         {
626           std::ostringstream oss;
627           oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
628           throw INTERP_KERNEL::Exception(oss.str().c_str());
629         }
630     }
631 }
632
633 /*!
634  * This method creates a new group called 'groupName' in 'this'. If it exists a group with the same name an INTERP_KERNEL::Exception will be thrown.
635  * If the 'meshDimRelToMaxExt' is not existing an INTERP_KERNEL::Exception will be thrown too.
636  * \b WARNING : This method does \b not garantee that 'groupName' lies only on a single level specified by 'meshDimRelToMaxExt'.
637  * in the case of a presence of one or more family id in family field at 'meshDimRelToMaxExt' level that appears in another level.
638  * If there is a risk of such case call MEDFileMesh::keepFamIdsOnlyOnLevs method \b before calling this method. 
639  * (call to MEDFileMesh::keepFamIdsOnlyOnLevs should be done with MEDFileMesh::getFamiliesIdsOnGroup('groupName' as first input ).
640  */
641 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName) throw(INTERP_KERNEL::Exception)
642 {
643   std::string grpName(groupName);
644   std::vector<int> levs=getNonEmptyLevelsExt();
645   if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
646     {
647       std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
648       oss << "Available relative ext levels are : ";
649       std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
650       throw INTERP_KERNEL::Exception(oss.str().c_str());
651     }
652   if(existsGroup(groupName))
653     {
654       std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
655       oss << "Already existing groups are : ";
656       std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
657       oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
658       throw INTERP_KERNEL::Exception(oss.str().c_str());
659     }
660   const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
661   if(fieldFamIds==0)
662     throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
663   std::set<int> famIds=fieldFamIds->getDifferentValues();
664   std::vector<std::string> familiesOnWholeGroup;
665   for(std::set<int>::const_iterator it=famIds.begin();it!=famIds.end();it++)
666     {
667       bool tmp;
668       familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
669     }
670   _groups[grpName]=familiesOnWholeGroup;
671 }
672
673 /*!
674  * This method checks that family Ids in 'famIds' are not present in levels \b not in 'vMeshDimRelToMaxExt'.
675  * If it is the case true is returned and 'this' is not modified.
676  * If there is some levels not in 'vMeshDimRelToMaxExt' where one or more family ids in 'famIds' appear
677  * new families are created and groups are updated in consequence.
678  */
679 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
680 {
681   std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
682   std::vector<int> levs=getNonEmptyLevelsExt();
683   std::set<int> levs2(levs.begin(),levs.end());
684   std::vector<int> levsToTest;
685   std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
686   std::set<int> famIds2(famIds.begin(),famIds.end());
687   bool ret=true;
688   int maxFamId=1;
689   if(!_families.empty())
690     maxFamId=getMaxFamilyId()+1;
691   std::vector<std::string> allFams=getFamiliesNames();
692   for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
693     {
694       const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
695       if(fieldFamIds)
696         {
697           std::set<int> famIds3=fieldFamIds->getDifferentValues();
698           std::vector<int> tmp;
699           std::set_intersection(famIds3.begin(),famIds3.end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
700           for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
701             {
702               ret=false;
703               std::string famName=getFamilyNameGivenId(*it2);
704               std::ostringstream oss; oss << "Family_" << maxFamId;
705               std::string zeName=CreateNameNotIn(oss.str(),allFams);
706               addFamilyOnAllGroupsHaving(famName.c_str(),zeName.c_str());
707               _families[zeName]=maxFamId;
708               (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
709               maxFamId++;
710             }
711         }
712     }
713   return ret;
714 }
715
716 /*!
717  * This method add into the family list of a group 'grpName' the family with name 'famName'.
718  * If the group 'grpName' does not exist it is created and 'famName' is added to the list.
719  * If the group 'grpName' already exists, 'famName' will be added into family list of the existing group.
720  * This method throws an INTERP_KERNEL::Exception if 'famName' does not exit.
721  */
722 void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) throw(INTERP_KERNEL::Exception)
723 {
724   std::string grpn(grpName);
725   std::string famn(famName);
726   if(grpn.empty() || famn.empty())
727     throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
728   std::vector<std::string> fams=getFamiliesNames();
729   if(std::find(fams.begin(),fams.end(),famn)==fams.end())
730     {
731       std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
732       oss << "Create this family or choose an existing one ! Existing fams are : ";
733       std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
734       throw INTERP_KERNEL::Exception(oss.str().c_str());
735     }
736   std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
737   if(it==_groups.end())
738     {
739       _groups[grpn].push_back(famn);
740     }
741   else
742     {
743       std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
744       if(it2==(*it).second.end())
745         (*it).second.push_back(famn);
746     }
747 }
748
749 /*!
750  * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
751  * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
752  * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
753  */
754 void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName) throw(INTERP_KERNEL::Exception)
755 {
756   std::string famNameCpp(famName);
757   std::string otherCpp(otherFamName);
758   for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
759     {
760       std::vector<std::string>& v=(*it).second;
761       if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
762         {
763           v.push_back(otherCpp);
764         }
765     }
766 }
767
768 void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
769 {
770   ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
771 }
772
773 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
774 {
775   std::string fam(familyNameToChange);
776   for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
777     {
778       std::vector<std::string>& fams((*it).second);
779       std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
780       if(it2!=fams.end())
781         {
782           fams.erase(it2);
783           fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
784         }
785     }
786 }
787
788 /*!
789  * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
790  * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
791  * If there is no family whose family id is equal to 'id' a family is created with a name different from those
792  * already existing. In this case 'created' will be returned with a value set to true, and internal state
793  * will be modified.
794  * This method will throws an exception if it is not possible to create a unique family name.
795  */
796 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception)
797 {
798   return FindOrCreateAndGiveFamilyWithId(_families,id,created);
799 }
800
801 /*!
802  * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
803  * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
804  * If there is no family whose family id is equal to 'id' a family is created with a name different from those
805  * already existing. In this case 'created' will be returned with a value set to true, and internal state
806  * will be modified.
807  * This method will throws an exception if it is not possible to create a unique family name.
808  */
809 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) throw(INTERP_KERNEL::Exception)
810 {
811   std::vector<std::string> famAlreadyExisting(families.size());
812   int ii=0;
813   for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
814     {
815       if((*it).second!=id)
816         {
817           famAlreadyExisting[ii]=(*it).first;
818         }
819       else
820         {
821           created=false;
822           return (*it).first;
823         }
824     }
825   created=true;
826   std::ostringstream oss; oss << "Family_" << id;
827   std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
828   families[ret]=id;
829   return ret;
830 }
831
832 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
833 {
834   _families=info;
835 }
836
837 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
838 {
839   _groups=info;
840 }
841
842 int MEDFileMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception)
843 {
844   std::string oname(name);
845   std::map<std::string, int>::const_iterator it=_families.find(oname);
846   std::vector<std::string> fams=getFamiliesNames();
847   if(it==_families.end())
848     {
849       std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
850       std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
851       throw INTERP_KERNEL::Exception(oss.str().c_str());
852     }
853   return (*it).second;
854 }
855
856 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
857 {
858   std::vector<int> ret(fams.size());
859   int i=0;
860   for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
861     {
862       std::map<std::string, int>::const_iterator it2=_families.find(*it);
863       if(it2==_families.end())
864         {
865           std::vector<std::string> fams2=getFamiliesNames();
866           std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
867           std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
868           throw INTERP_KERNEL::Exception(oss.str().c_str());
869         }
870       ret[i]=(*it2).second;
871     }
872   return ret;
873 }
874
875 int MEDFileMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception)
876 {
877   if(_families.empty())
878     throw INTERP_KERNEL::Exception("MEDFileUMesh::getMaxFamilyId : no families set !");
879   int ret=-std::numeric_limits<int>::max();
880   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
881     {
882       ret=std::max((*it).second,ret);
883     }
884   return ret;
885 }
886
887 int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception)
888 {
889   if(_families.empty())
890     throw INTERP_KERNEL::Exception("MEDFileUMesh::getMinFamilyId : no families set !");
891   int ret=std::numeric_limits<int>::max();
892   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
893     {
894       ret=std::min((*it).second,ret);
895     }
896   return ret;
897 }
898
899 int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception)
900 {
901   int m1=-std::numeric_limits<int>::max();
902   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
903     m1=std::max((*it).second,m1);
904   int m2=getMaxFamilyIdInArrays();
905   return std::max(m1,m2);
906 }
907
908 int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception)
909 {
910   int m1=std::numeric_limits<int>::max();
911   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
912     m1=std::min((*it).second,m1);
913   int m2=getMinFamilyIdInArrays();
914   return std::min(m1,m2);
915 }
916
917 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception)
918 {
919   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
920   std::set<int> v;
921   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
922     v.insert((*it).second);
923   ret->alloc((int)v.size(),1);
924   std::copy(v.begin(),v.end(),ret->getPointer());
925   return ret.retn();
926 }
927
928 /*!
929  * true is returned if no modification has been needed. false if family
930  * renumbering has been needed.       
931  */
932 bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception)
933 {
934   std::vector<int> levs=getNonEmptyLevelsExt();
935   std::set<int> allFamIds;
936   int maxId=getMaxFamilyId()+1;
937   std::map<int,std::vector<int> > famIdsToRenum;
938   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
939     {
940       const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
941       if(fam)
942         {
943           std::set<int> tmp=fam->getDifferentValues();
944           std::set<int> r2;
945           std::set_intersection(tmp.begin(),tmp.end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
946           if(!r2.empty())
947             famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
948           std::set<int> r3;
949           std::set_union(tmp.begin(),tmp.end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
950         }
951     }
952   if(famIdsToRenum.empty())
953     return true;
954   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
955   for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
956     {
957       DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
958       int *famIdsToChange=fam->getPointer();
959       std::map<int,int> ren;
960       for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
961         {
962           if(allIds->presenceOfValue(*it3))
963             {
964               std::string famName=getFamilyNameGivenId(*it3);
965               std::vector<std::string> grps=getGroupsOnFamily(famName.c_str());
966               ren[*it3]=maxId;
967               bool dummy;
968               std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
969               for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
970                 addFamilyOnGrp((*it4).c_str(),newFam.c_str());
971             }
972         }
973       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
974       for(const int *id=ids->begin();id!=ids->end();id++)
975         famIdsToChange[*id]=ren[famIdsToChange[*id]];
976     }
977   return false;
978 }
979
980 /*!
981  * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
982  * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
983  * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
984  * This method will throw an exception if a same family id is detected in different level.
985  * \warning This policy is the opposite of those in MED file documentation ...
986  */
987 void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
988 {
989   ensureDifferentFamIdsPerLevel();
990   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
991   std::vector<int> levs=getNonEmptyLevelsExt();
992   std::set<int> levsS(levs.begin(),levs.end());
993   std::set<std::string> famsFetched;
994   std::map<std::string,int> families;
995   if(std::find(levs.begin(),levs.end(),0)!=levs.end())
996     {
997       levsS.erase(0);
998       const DataArrayInt *fam=getFamilyFieldAtLevel(0);
999       if(fam)
1000         {
1001           int refId=1;
1002           std::set<int> tmp=fam->getDifferentValues();
1003           std::map<int,int> ren;
1004           for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++,refId++)
1005             ren[*it]=refId;
1006           int nbOfTuples=fam->getNumberOfTuples();
1007           int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1008           for(int *w=start;w!=start+nbOfTuples;w++)
1009             *w=ren[*w];
1010           for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++)
1011             {
1012               if(allIds->presenceOfValue(*it))
1013                 {
1014                   std::string famName=getFamilyNameGivenId(*it);
1015                   families[famName]=ren[*it];
1016                   famsFetched.insert(famName);
1017                 }
1018             }
1019         }
1020     }
1021   if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1022     {
1023       levsS.erase(-1);
1024       const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1025       if(fam)
1026         {
1027           int refId=-1;
1028           std::set<int> tmp=fam->getDifferentValues();
1029           std::map<int,int> ren;
1030           for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++,refId--)
1031             ren[*it]=refId;
1032           int nbOfTuples=fam->getNumberOfTuples();
1033           int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1034           for(int *w=start;w!=start+nbOfTuples;w++)
1035             *w=ren[*w];
1036           for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++)
1037             {
1038               if(allIds->presenceOfValue(*it))
1039                 {
1040                   std::string famName=getFamilyNameGivenId(*it);
1041                   families[famName]=ren[*it];
1042                   famsFetched.insert(famName);
1043                 }
1044             }
1045         }
1046     }
1047   for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1048     {
1049       DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1050       if(fam)
1051         {
1052           std::set<int> tmp=fam->getDifferentValues();
1053           fam->fillWithZero();
1054           for(std::set<int>::const_iterator it3=tmp.begin();it3!=tmp.end();it3++)
1055             if(allIds->presenceOfValue(*it3))
1056               {
1057                 std::string famName=getFamilyNameGivenId(*it3);
1058                 families[famName]=0;
1059                 famsFetched.insert(famName);
1060               }
1061         }
1062     }
1063   //
1064   std::vector<std::string> allFams=getFamiliesNames();
1065   std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1066   std::set<std::string> unFetchedIds;
1067   std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1068   for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1069     families[*it4]=_families[*it4];
1070   _families=families;
1071 }
1072
1073 /*!
1074  * This method normalizes fam id with the following policy.
1075  * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1076  * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1077  * This method will throw an exception if a same family id is detected in different level.
1078  */
1079 void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
1080 {
1081   ensureDifferentFamIdsPerLevel();
1082   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1083   std::vector<int> levs=getNonEmptyLevelsExt();
1084   std::set<int> levsS(levs.begin(),levs.end());
1085   std::set<std::string> famsFetched;
1086   std::map<std::string,int> families;
1087   int refId=1;
1088   if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1089     {
1090       levsS.erase(1);
1091       const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1092       if(fam)
1093         {
1094           std::set<int> tmp=fam->getDifferentValues();
1095           std::map<int,int> ren;
1096           for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++,refId++)
1097             ren[*it]=refId;
1098           int nbOfTuples=fam->getNumberOfTuples();
1099           int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1100           for(int *w=start;w!=start+nbOfTuples;w++)
1101             *w=ren[*w];
1102           for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++)
1103             {
1104               if(allIds->presenceOfValue(*it))
1105                 {
1106                   std::string famName=getFamilyNameGivenId(*it);
1107                   families[famName]=ren[*it];
1108                   famsFetched.insert(famName);
1109                 }
1110             }
1111         }
1112     }
1113   refId=-1;
1114   for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1115     {
1116       const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1117       if(fam)
1118         {
1119           std::set<int> tmp=fam->getDifferentValues();
1120           std::map<int,int> ren;
1121           for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++,refId--)
1122             ren[*it]=refId;
1123           int nbOfTuples=fam->getNumberOfTuples();
1124           int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1125           for(int *w=start;w!=start+nbOfTuples;w++)
1126             *w=ren[*w];
1127           for(std::set<int>::const_iterator it=tmp.begin();it!=tmp.end();it++)
1128             {
1129               if(allIds->presenceOfValue(*it))
1130                 {
1131                   std::string famName=getFamilyNameGivenId(*it);
1132                   families[famName]=ren[*it];
1133                   famsFetched.insert(famName);
1134                 }
1135             }
1136         }
1137     }
1138   //
1139   std::vector<std::string> allFams=getFamiliesNames();
1140   std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1141   std::set<std::string> unFetchedIds;
1142   std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1143   for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1144     families[*it4]=_families[*it4];
1145   _families=families;
1146 }
1147
1148 /*!
1149  * Returns the first (in lexical order) family name having family id equal to 'id'.
1150  */
1151 std::string MEDFileMesh::getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception)
1152 {
1153   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1154     if((*it).second==id)
1155       return (*it).first;
1156   std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1157   throw INTERP_KERNEL::Exception(oss.str().c_str());
1158 }
1159
1160 std::string MEDFileMesh::simpleRepr() const
1161 {
1162   std::ostringstream oss;
1163   oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1164   oss << "- Name of the mesh : <<" << getName() << ">>\n";
1165   oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1166   return oss.str();
1167 }
1168
1169 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1170 {
1171   std::vector<std::string> tmp(1);
1172   tmp[0]=grp;
1173   DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1174   ret->setName(grp);
1175   return ret;
1176 }
1177
1178 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1179 {
1180   std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1181   return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1182 }
1183
1184 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1185 {
1186   std::vector<std::string> tmp(1);
1187   tmp[0]=fam;
1188   DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1189   ret->setName(fam);
1190   return ret;
1191 }
1192
1193 DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1194 {
1195   std::vector<std::string> tmp(1);
1196   tmp[0]=grp;
1197   DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1198   ret->setName(grp);
1199   return ret;
1200 }
1201
1202 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1203 {
1204   return getGroupsArr(1,grps,renum);
1205 }
1206
1207 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1208 {
1209   std::vector<std::string> tmp(1);
1210   tmp[0]=fam;
1211   DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1212   ret->setName(fam);
1213   return ret;
1214 }
1215
1216 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
1217 {
1218   return getFamiliesArr(1,fams,renum);
1219 }
1220
1221 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum) throw(INTERP_KERNEL::Exception)
1222 {
1223   if(grps.empty())
1224     return ;
1225   std::set<std::string> grpsName;
1226   std::vector<std::string> grpsName2(grps.size());
1227   int i=0;
1228
1229   for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1230     {
1231       grpsName.insert((*it)->getName());
1232       grpsName2[i]=(*it)->getName();
1233     }
1234   if(grpsName.size()!=grps.size())
1235     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1236   if(grpsName.find(std::string(""))!=grpsName.end())
1237     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1238   int sz=getSizeAtLevel(meshDimRelToMaxExt);
1239   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1240   std::vector< std::vector<int> > fidsOfGroups;
1241   if(!renum)
1242     {
1243       fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1244     }
1245   else
1246     {
1247       std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1248       for(unsigned int ii=0;ii<grps.size();ii++)
1249         {
1250           grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1251           grps2[ii]->setName(grps[ii]->getName().c_str());
1252         }
1253       std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1254       fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1255     }
1256   int offset=1;
1257   if(!_families.empty())
1258     offset=getMaxFamilyId()+1;
1259   TranslateFamilyIds(offset,fam,fidsOfGroups);
1260   std::set<int> ids=fam->getDifferentValues();
1261   appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1262   setFamilyFieldArr(meshDimRelToMaxExt,fam);
1263 }
1264
1265 /*!
1266  * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1267  * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1268  * For the moment, the two last input parameters are not taken into account.
1269  */
1270 void MEDFileMesh::appendFamilyEntries(const std::set<int>& famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1271 {
1272   std::map<int,std::string> famInv;
1273   for(std::set<int>::const_iterator it=famIds.begin();it!=famIds.end();it++)
1274     {
1275       std::ostringstream oss;
1276       oss << "Family_" << (*it);
1277       _families[oss.str()]=(*it);
1278       famInv[*it]=oss.str();
1279     }
1280   int i=0;
1281   for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1282     {
1283       for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1284         {
1285           _groups[grpNames[i]].push_back(famInv[*it2]);
1286         }
1287     }
1288 }
1289
1290 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1291 {
1292   famArr->applyLin(1,offset,0);
1293   for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1294     std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1295 }
1296
1297 /*!
1298  * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1299  * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1300  * If this method fails to find such a name it will throw an exception.
1301  */
1302 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) throw(INTERP_KERNEL::Exception)
1303 {
1304   //attempt #0
1305   if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1306     return nameTry;
1307   //attempt #1
1308   std::size_t len=nameTry.length();
1309   for(std::size_t ii=1;ii<len;ii++)
1310     {
1311       std::string tmp=nameTry.substr(ii,len-ii);
1312       if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1313         return tmp;
1314     }
1315   //attempt #2
1316   if(len>=1)
1317     {
1318       for(std::size_t i=1;i<30;i++)
1319         {
1320           std::string tmp1(nameTry.at(0),i);
1321           tmp1+=nameTry;
1322           if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1323             return tmp1;
1324         }
1325     }
1326   //attempt #3
1327   std::string tmp2;
1328   for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1329     tmp2+=(*it2);
1330   if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1331     return tmp2;
1332   throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1333 }
1334
1335 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) throw(INTERP_KERNEL::Exception)
1336 {
1337   std::size_t nbOfChunks=code.size()/3;
1338   if(code.size()%3!=0)
1339     throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1340   int ret=strt;
1341   for(std::size_t i=0;i<nbOfChunks;i++)
1342     {
1343       code[3*i+2]=ret;
1344       ret+=code[3*i+1];
1345     }
1346   return ret;
1347 }
1348
1349 /*!
1350  * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1351  * If _name attribute is empty the name of 'm' if taken as _name attribute.
1352  * If _name is not empty and that 'm' has the same name nothing is done.
1353  * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1354  */
1355 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL::Exception)
1356 {
1357   if(_name.empty())
1358     _name=m->getName();
1359   else
1360     {
1361       std::string name(m->getName());
1362       if(!name.empty())
1363         {
1364           if(_name!=name)
1365             {
1366               std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1367               oss << name << "' ! Names must match !";
1368               throw INTERP_KERNEL::Exception(oss.str().c_str());
1369             }
1370         }
1371     }
1372   if(_desc_name.empty())
1373     _desc_name=m->getDescription();
1374   else
1375     {
1376       std::string name(m->getDescription());
1377       if(!name.empty())
1378         {
1379           if(_desc_name!=name)
1380             {
1381               std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1382               oss << name << "' ! Names must match !";
1383               throw INTERP_KERNEL::Exception(oss.str().c_str());
1384             }
1385         }
1386     }
1387 }
1388
1389 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1390 {
1391   oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1392   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1393     {
1394       oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1395       oss << "  - Groups lying on this family : ";
1396       std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
1397       std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1398       oss << std::endl << std::endl;
1399     }
1400 }
1401
1402 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
1403 {
1404   MEDFileUtilities::CheckFileForRead(fileName);
1405   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1406   return new MEDFileUMesh(fid,mName,dt,it);
1407 }
1408
1409 MEDFileUMesh *MEDFileUMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
1410 {
1411   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1412   if(ms.empty())
1413     {
1414       std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1415       throw INTERP_KERNEL::Exception(oss.str().c_str());
1416     }
1417   MEDFileUtilities::CheckFileForRead(fileName);
1418   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1419   int dt,it;
1420   ParaMEDMEM::MEDCouplingMeshType meshType;
1421   std::string dummy2;
1422   MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
1423   return new MEDFileUMesh(fid,ms.front().c_str(),dt,it);
1424 }
1425
1426 MEDFileUMesh *MEDFileUMesh::New()
1427 {
1428   return new MEDFileUMesh;
1429 }
1430
1431 std::size_t MEDFileUMesh::getHeapMemorySize() const
1432 {
1433   std::size_t ret=MEDFileMesh::getHeapMemorySize();
1434   if((const DataArrayDouble*)_coords)
1435     ret+=_coords->getHeapMemorySize();
1436   if((const DataArrayInt *)_fam_coords)
1437     ret+=_fam_coords->getHeapMemorySize();
1438   if((const DataArrayInt *)_num_coords)
1439     ret+=_num_coords->getHeapMemorySize();
1440   if((const DataArrayInt *)_rev_num_coords)
1441     ret+=_rev_num_coords->getHeapMemorySize();
1442   ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1443   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1444     if((const MEDFileUMeshSplitL1*) *it)
1445       ret+=(*it)->getHeapMemorySize();
1446   return ret;
1447 }
1448
1449 MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
1450 {
1451   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1452   return ret.retn();
1453 }
1454
1455 MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
1456 {
1457   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1458   if((const DataArrayDouble*)_coords)
1459     ret->_coords=_coords->deepCpy();
1460   if((const DataArrayInt*)_fam_coords)
1461     ret->_fam_coords=_fam_coords->deepCpy();
1462   if((const DataArrayInt*)_num_coords)
1463     ret->_num_coords=_num_coords->deepCpy();
1464   if((const DataArrayInt*)_rev_num_coords)
1465     ret->_rev_num_coords=_rev_num_coords->deepCpy();
1466   std::size_t i=0;
1467   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
1468     {
1469       if((const MEDFileUMeshSplitL1 *)(*it))
1470         ret->_ms[i]=(*it)->deepCpy();
1471     }
1472   return ret.retn();
1473 }
1474
1475 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
1476 {
1477   if(!MEDFileMesh::isEqual(other,eps,what))
1478     return false;
1479   const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
1480   if(!otherC)
1481     {
1482       what="Mesh types differ ! This is unstructured and other is NOT !";
1483       return false;
1484     }
1485   clearNonDiscrAttributes();
1486   otherC->clearNonDiscrAttributes();
1487   const DataArrayDouble *coo1=_coords;
1488   const DataArrayDouble *coo2=otherC->_coords;
1489   if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
1490     {
1491       what="Mismatch of coordinates ! One is defined and not other !";
1492       return false;
1493     }
1494   if(coo1)
1495     {
1496       bool ret=coo1->isEqual(*coo2,eps);
1497       if(!ret)
1498         {
1499           what="Coords differ !";
1500           return false;
1501         }
1502     }
1503   const DataArrayInt *famc1=_fam_coords;
1504   const DataArrayInt *famc2=otherC->_fam_coords;
1505   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
1506     {
1507       what="Mismatch of families arr on nodes ! One is defined and not other !";
1508       return false;
1509     }
1510   if(famc1)
1511     {
1512       bool ret=famc1->isEqual(*famc2);
1513       if(!ret)
1514         {
1515           what="Families arr on node differ !";
1516           return false;
1517         }
1518     }
1519   const DataArrayInt *numc1=_num_coords;
1520   const DataArrayInt *numc2=otherC->_num_coords;
1521   if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
1522     {
1523       what="Mismatch of numbering arr on nodes ! One is defined and not other !";
1524       return false;
1525     }
1526   if(numc1)
1527     {
1528       bool ret=numc1->isEqual(*numc2);
1529       if(!ret)
1530         {
1531           what="Numbering arr on node differ !";
1532           return false;
1533         }
1534     }
1535   if(_ms.size()!=otherC->_ms.size())
1536     {
1537       what="Number of levels differs !";
1538       return false;
1539     }
1540   std::size_t sz=_ms.size();
1541   for(std::size_t i=0;i<sz;i++)
1542     {
1543       const MEDFileUMeshSplitL1 *s1=_ms[i];
1544       const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
1545       if((s1==0 && s2!=0) || (s1!=0 && s2==0))
1546         {
1547           what="Mismatch of presence of sub levels !";
1548           return false;
1549         }
1550       if(s1)
1551         {
1552           bool ret=s1->isEqual(s2,eps,what);
1553           if(!ret)
1554             return false;
1555         }
1556     }
1557   return true;
1558 }
1559
1560 void MEDFileUMesh::clearNonDiscrAttributes() const
1561 {
1562   MEDFileMesh::clearNonDiscrAttributes();
1563   const DataArrayDouble *coo1=_coords;
1564   if(coo1)
1565     (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
1566   const DataArrayInt *famc1=_fam_coords;
1567   if(famc1)
1568     (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
1569   const DataArrayInt *numc1=_num_coords;
1570   if(numc1)
1571     (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
1572   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1573     {
1574       const MEDFileUMeshSplitL1 *tmp=(*it);
1575       if(tmp)
1576         tmp->clearNonDiscrAttributes();
1577     }
1578 }
1579
1580 MEDFileUMesh::MEDFileUMesh()
1581 {
1582 }
1583
1584 MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
1585 try
1586   {
1587     loadUMeshFromFile(fid,mName,dt,it);
1588   }
1589 catch(INTERP_KERNEL::Exception& e)
1590   {
1591     throw e;
1592   }
1593
1594 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
1595 {
1596   MEDFileUMeshL2 loaderl2;
1597   ParaMEDMEM::MEDCouplingMeshType meshType;
1598   int dummy0,dummy1;
1599   std::string dummy2;
1600   int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
1601   if(meshType!=UNSTRUCTURED)
1602     {
1603       std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
1604       throw INTERP_KERNEL::Exception(oss.str().c_str());
1605     }
1606   loaderl2.loadAll(fid,mid,mName,dt,it);
1607   int lev=loaderl2.getNumberOfLevels();
1608   _ms.resize(lev);
1609   for(int i=0;i<lev;i++)
1610     {
1611       if(!loaderl2.emptyLev(i))
1612         _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
1613       else
1614         _ms[i]=0;
1615     }
1616   MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups);
1617   //
1618   setName(loaderl2.getName());
1619   setDescription(loaderl2.getDescription());
1620   setIteration(loaderl2.getIteration());
1621   setOrder(loaderl2.getOrder());
1622   setTimeValue(loaderl2.getTime());
1623   setTimeUnit(loaderl2.getTimeUnit());
1624   _coords=loaderl2.getCoords();
1625   _fam_coords=loaderl2.getCoordsFamily();
1626   _num_coords=loaderl2.getCoordsNum();
1627   computeRevNum();
1628 }
1629
1630 MEDFileUMesh::~MEDFileUMesh()
1631 {
1632 }
1633
1634 void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
1635 {
1636   const DataArrayDouble *coo=_coords;
1637   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1638   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
1639   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
1640   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
1641   int spaceDim=coo?coo->getNumberOfComponents():0;
1642   int mdim=getMeshDimension();
1643   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
1644   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
1645   for(int i=0;i<spaceDim;i++)
1646     {
1647       std::string info=coo->getInfoOnComponent(i);
1648       std::string c,u;
1649       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
1650       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
1651       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
1652     }
1653   MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
1654   MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords);
1655   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1656     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
1657       (*it)->write(fid,maa,mdim);
1658   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
1659 }
1660
1661 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
1662 {
1663   std::vector<int> ret;
1664   int lev=0;
1665   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
1666     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
1667       if(!(*it)->empty())
1668         ret.push_back(lev);
1669   return ret;
1670 }
1671
1672 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
1673 {
1674   std::vector<int> ret0=getNonEmptyLevels();
1675   if((const DataArrayDouble *) _coords)
1676     {
1677       std::vector<int> ret(ret0.size()+1);
1678       ret[0]=1;
1679       std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
1680       return ret;
1681     }
1682   return ret0;
1683 }
1684
1685 /*!
1686  * This methods returns all relative mesh levels where group 'grp' is defined \b excluded \b nodes.
1687  * To include nodes call MEDFileUMesh::getGrpNonEmptyLevelsExt method.
1688  */
1689 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception)
1690 {
1691   std::vector<std::string> fams=getFamiliesOnGroup(grp);
1692   return getFamsNonEmptyLevels(fams);
1693 }
1694
1695 /*!
1696  * This method is a generalization of MEDFileUMesh::getGrpNonEmptyLevelsExt. It looks at the node level to state if the group 'grp' has a part lying on node.
1697  */
1698 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception)
1699 {
1700   std::vector<std::string> fams=getFamiliesOnGroup(grp);
1701   return getFamsNonEmptyLevelsExt(fams);
1702 }
1703
1704 /*!
1705  * This methods returns all relative mesh levels where family 'fam' is defined \b excluded \b nodes.
1706  * To include nodes call MEDFileUMesh::getFamNonEmptyLevelsExt method.
1707  */
1708 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw(INTERP_KERNEL::Exception)
1709 {
1710   std::vector<std::string> fams(1,std::string(fam));
1711   return getFamsNonEmptyLevels(fams);
1712 }
1713
1714 /*!
1715  * This method is a generalization of MEDFileUMesh::getFamNonEmptyLevels. It looks at the node level to state if the family 'fam' has a part lying on node.
1716  */
1717 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const throw(INTERP_KERNEL::Exception)
1718 {
1719   std::vector<std::string> fams(1,std::string(fam));
1720   return getFamsNonEmptyLevelsExt(fams);
1721 }
1722
1723 /*!
1724  * This methods returns all relative mesh levels where groups 'grps' are defined \b excluded \b nodes.
1725  * To include nodes call MEDFileUMesh::getGrpsNonEmptyLevelsExt method.
1726  */
1727 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
1728 {
1729   std::vector<std::string> fams=getFamiliesOnGroups(grps);
1730   return getFamsNonEmptyLevels(fams);
1731 }
1732
1733 /*!
1734  * This method is a generalization of MEDFileUMesh::getGrpsNonEmptyLevels. It looks at the node level to state if the families 'fams' has a part lying on node.
1735  */
1736 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
1737 {
1738   std::vector<std::string> fams=getFamiliesOnGroups(grps);
1739   return getFamsNonEmptyLevelsExt(fams);
1740 }
1741
1742 /*!
1743  * This methods returns all relative mesh levels where families 'fams' are defined \b excluded \b nodes.
1744  * To include nodes call MEDFileUMesh::getFamsNonEmptyLevelsExt method.
1745  */
1746 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
1747 {
1748   std::vector<int> ret;
1749   std::vector<int> levs=getNonEmptyLevels();
1750   std::vector<int> famIds=getFamiliesIds(fams);
1751   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1752     if(_ms[-(*it)]->presenceOfOneFams(famIds))
1753       ret.push_back(*it);
1754   return ret;
1755 }
1756
1757 /*!
1758  * This method is a generalization of MEDFileUMesh::getFamsNonEmptyLevels. It looks at the node level to state if the families 'fams' has a part lying on node.
1759  */
1760 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
1761 {
1762   std::vector<int> ret0=getFamsNonEmptyLevels(fams);
1763   const DataArrayInt *famCoords=_fam_coords;
1764   if(!famCoords)
1765     return ret0;
1766   std::vector<int> famIds=getFamiliesIds(fams);
1767   if(famCoords->presenceOfValue(famIds))
1768     {
1769       std::vector<int> ret(ret0.size()+1);
1770       ret[0]=1;
1771       std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
1772       return ret;
1773     }
1774   else
1775     return ret0;
1776 }
1777
1778 /*!
1779  * This method retrives all groups that partly or fully appear on the level 'meshDimRelToMaxExt'.
1780  */
1781 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1782 {
1783   std::vector<std::string> ret;
1784   std::vector<std::string> allGrps=getGroupsNames();
1785   for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
1786     {
1787       std::vector<int> levs=getGrpNonEmptyLevelsExt((*it).c_str());
1788       if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
1789         ret.push_back(*it);
1790     }
1791   return ret;
1792 }
1793
1794 int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
1795 {
1796   int ret=-std::numeric_limits<int>::max(),tmp=-1;
1797   if((const DataArrayInt *)_fam_coords)
1798     {
1799       int val=_fam_coords->getMaxValue(tmp);
1800       ret=std::max(ret,val);
1801     }
1802   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1803     {
1804       if((const MEDFileUMeshSplitL1 *)(*it))
1805         {
1806           const DataArrayInt *da=(*it)->getFamilyField();
1807           if(da)
1808             {
1809               int val=_fam_coords->getMaxValue(tmp);
1810               ret=std::max(ret,val);
1811             }
1812         }
1813     }
1814   return ret;
1815 }
1816
1817 int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
1818 {
1819   int ret=std::numeric_limits<int>::max(),tmp=-1;
1820   if((const DataArrayInt *)_fam_coords)
1821     {
1822       int val=_fam_coords->getMinValue(tmp);
1823       ret=std::min(ret,val);
1824     }
1825   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1826     {
1827       if((const MEDFileUMeshSplitL1 *)(*it))
1828         {
1829           const DataArrayInt *da=(*it)->getFamilyField();
1830           if(da)
1831             {
1832               int val=_fam_coords->getMinValue(tmp);
1833               ret=std::min(ret,val);
1834             }
1835         }
1836     }
1837   return ret;
1838 }
1839
1840 int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
1841 {
1842   int lev=0;
1843   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
1844     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
1845       return (*it)->getMeshDimension()+lev;
1846   throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
1847 }
1848
1849 int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
1850 {
1851   const DataArrayDouble *coo=_coords;
1852   if(!coo)
1853     throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
1854   return coo->getNumberOfComponents();
1855 }
1856
1857 std::string MEDFileUMesh::simpleRepr() const
1858 {
1859   std::ostringstream oss;
1860   oss << MEDFileMesh::simpleRepr();
1861   const DataArrayDouble *coo=_coords;
1862   oss << "- The dimension of the space is ";
1863   static const char MSG1[]= "*** NO COORDS SET ***";
1864   static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
1865   if(coo)
1866     oss << _coords->getNumberOfComponents() << std::endl;
1867   else
1868     oss << MSG1 << std::endl;
1869   oss << "- Type of the mesh : UNSTRUCTURED\n";
1870   oss << "- Number of nodes : ";
1871   if(coo)
1872     oss << _coords->getNumberOfTuples() << std::endl;
1873   else
1874     oss << MSG1 << std::endl;
1875   std::size_t nbOfLev=_ms.size();
1876   oss << "- Number of levels allocated : " << nbOfLev << std::endl;
1877   for(std::size_t i=0;i<nbOfLev;i++)
1878     {
1879       const MEDFileUMeshSplitL1 *lev=_ms[i];
1880       oss << "  - Level #" << -((int) i) << " has dimension : ";
1881       if(lev)
1882         {
1883           oss << lev->getMeshDimension() << std::endl;
1884           lev->simpleRepr(oss);
1885         }
1886       else
1887         oss << MSG2 << std::endl;
1888     }
1889   oss << "- Number of families : " << _families.size() << std::endl << std::endl;
1890   if(coo)
1891     {
1892       oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
1893       oss << "- Names of coordinates :" << std::endl;
1894       std::vector<std::string> vars=coo->getVarsOnComponent();
1895       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
1896       oss << std::endl << "- Units of coordinates : " << std::endl;
1897       std::vector<std::string> units=coo->getUnitsOnComponent();
1898       std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
1899     }
1900   oss << std::endl << std::endl;
1901   getFamilyRepr(oss);
1902   return oss.str();
1903 }
1904
1905 std::string MEDFileUMesh::advancedRepr() const
1906 {
1907   return simpleRepr();
1908 }
1909
1910 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1911 {
1912   if(meshDimRelToMaxExt==1)
1913     {
1914       if(!((const DataArrayDouble *)_coords))
1915         throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
1916       return _coords->getNumberOfTuples();
1917     }
1918   return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
1919 }
1920
1921 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1922 {
1923   if(meshDimRelToMaxExt==1)
1924     return _fam_coords;
1925   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
1926   return l1->getFamilyField();
1927 }
1928
1929 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1930 {
1931   if(meshDimRelToMaxExt==1)
1932     return _num_coords;
1933   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
1934   return l1->getNumberField();
1935 }
1936
1937 int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
1938 {
1939   const DataArrayDouble *coo=_coords;
1940   if(!coo)
1941     throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
1942   return coo->getNumberOfTuples();
1943 }
1944
1945 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1946 {
1947   if(meshDimRelToMaxExt==1)
1948     {
1949       if(!((const DataArrayInt *)_num_coords))
1950         throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
1951       return _rev_num_coords;
1952     }
1953   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
1954   return l1->getRevNumberField();
1955 }
1956
1957 /*!
1958  * This method returns coordinates in 'this'. The returned array reference counter is \b not incremented by this method (as MEDCouplingPointSet::getCoords does).
1959  */
1960 DataArrayDouble *MEDFileUMesh::getCoords() const
1961 {
1962   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
1963   if((DataArrayDouble *)tmp)
1964     {
1965       return tmp;
1966     }
1967   return 0;
1968 }
1969
1970 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1971 {
1972   synchronizeTinyInfoOnLeaves();
1973   std::vector<std::string> tmp(1);
1974   tmp[0]=grp;
1975   MEDCouplingUMesh *ret=getGroups(meshDimRelToMaxExt,tmp,renum);
1976   ret->setName(grp);
1977   return ret;
1978 }
1979
1980 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1981 {
1982   synchronizeTinyInfoOnLeaves();
1983   std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1984   return getFamilies(meshDimRelToMaxExt,fams2,renum);
1985 }
1986
1987 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1988 {
1989   synchronizeTinyInfoOnLeaves();
1990   std::vector<std::string> tmp(1);
1991   tmp[0]=fam;
1992   MEDCouplingUMesh *ret=getFamilies(meshDimRelToMaxExt,tmp,renum);
1993   ret->setName(fam);
1994   return ret;
1995 }
1996
1997 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
1998 {
1999   synchronizeTinyInfoOnLeaves();
2000   if(meshDimRelToMaxExt==1)
2001     {
2002       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2003       MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2004       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2005       ret->setCoords(c);
2006       return ret.retn();
2007     }
2008   std::vector<int> famIds=getFamiliesIds(fams);
2009   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2010   if(!famIds.empty())
2011     return l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2012   else
2013     return l1->getFamilyPart(0,0,renum);
2014 }
2015
2016 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2017 {
2018   std::vector<int> famIds=getFamiliesIds(fams);
2019   if(meshDimRelToMaxExt==1)
2020     {
2021       if((const DataArrayInt *)_fam_coords)
2022         {
2023           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2024           if(!famIds.empty())
2025             da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2026           else
2027             da=_fam_coords->getIdsEqualList(0,0);
2028           if(renum)
2029             return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2030           else
2031             return da.retn();
2032         }
2033       else
2034         throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2035     }
2036   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2037   if(!famIds.empty())
2038     return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2039   else
2040     return l1->getFamilyPartArr(0,0,renum);
2041 }
2042
2043 /*!
2044  * Returns a pointer to mesh at the specified level.
2045  * 
2046  * \return a pointer to unstructured mesh that need to be managed by the caller.
2047  * \warning the returned pointer has to be managed by the caller.
2048  * \sa MEDFileUMesh::getGenMeshAtLevel
2049  */
2050 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
2051 {
2052   synchronizeTinyInfoOnLeaves();
2053   if(meshDimRelToMaxExt==1)
2054     {
2055       if(!renum)
2056         {
2057           MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2058           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2059           umesh->setCoords(cc);
2060           MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2061           umesh->setName(getName());
2062           return umesh;
2063         }
2064     }
2065   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2066   return l1->getWholeMesh(renum);
2067 }
2068
2069 /*!
2070  * Returns a pointer to mesh at the specified level.
2071  * 
2072  * \return a pointer to unstructured mesh that need to be managed by the caller.
2073  * \warning the returned pointer has to be managed by the caller.
2074  * \sa MEDFileUMesh::getMeshAtLevel
2075  */
2076 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
2077 {
2078   return getMeshAtLevel(meshDimRelToMax,renum);
2079 }
2080
2081 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2082 {
2083   return getMeshAtLevel(0,renum);
2084 }
2085
2086 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2087 {
2088   return getMeshAtLevel(-1,renum);
2089 }
2090
2091 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2092 {
2093   return getMeshAtLevel(-2,renum);
2094 }
2095
2096 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2097 {
2098   return getMeshAtLevel(-3,renum);
2099 }
2100
2101 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2102 {
2103   if(meshDimRelToMaxExt==1)
2104     throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2105   if(meshDimRelToMaxExt>1)
2106     throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2107   int tracucedRk=-meshDimRelToMaxExt;
2108   if(tracucedRk>=(int)_ms.size())
2109     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2110   if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2111     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2112   return _ms[tracucedRk];
2113 }
2114
2115 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2116 {
2117    if(meshDimRelToMaxExt==1)
2118     throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2119   if(meshDimRelToMaxExt>1)
2120     throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2121   int tracucedRk=-meshDimRelToMaxExt;
2122   if(tracucedRk>=(int)_ms.size())
2123     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2124   if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2125     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2126   return _ms[tracucedRk];
2127 }
2128
2129 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2130 {
2131   if(-meshDimRelToMax>=(int)_ms.size())
2132     throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
2133   int i=0;
2134   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2135     {
2136       if(((const MEDFileUMeshSplitL1*) (*it))!=0)
2137         {
2138           int ref=(*it)->getMeshDimension();
2139           if(ref+i!=meshDim-meshDimRelToMax)
2140             throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
2141         }
2142     }
2143 }
2144
2145 void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
2146 {
2147   if(!coords)
2148     throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
2149   coords->checkAllocated();
2150   int nbOfTuples=coords->getNumberOfTuples();
2151   _coords=coords;
2152   coords->incrRef();
2153   _fam_coords=DataArrayInt::New();
2154   _fam_coords->alloc(nbOfTuples,1);
2155   _fam_coords->fillWithZero();
2156 }
2157
2158 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2159 {
2160   if(meshDimRelToMaxExt==1)
2161     {
2162       if((DataArrayInt *)_fam_coords)
2163         _fam_coords->fillWithZero();
2164       return ;
2165     }
2166   MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2167   l1->eraseFamilyField();
2168   optimizeFamilies();
2169 }
2170
2171 void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
2172 {
2173   std::vector<int> levs=getNonEmptyLevelsExt();
2174   std::set<int> allFamsIds;
2175   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2176     {
2177       const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
2178       std::set<int> ids=ffield->getDifferentValues();
2179       std::set<int> res;
2180       std::set_union(ids.begin(),ids.end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
2181       allFamsIds=res;
2182     }
2183   std::set<std::string> famNamesToKill;
2184   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2185     {
2186       if(allFamsIds.find((*it).second)!=allFamsIds.end())
2187         famNamesToKill.insert((*it).first);
2188     }
2189   for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
2190     _families.erase(*it);
2191   std::vector<std::string> grpNamesToKill;
2192   for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
2193     {
2194       std::vector<std::string> tmp;
2195       for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
2196         {
2197           if(famNamesToKill.find(*it2)==famNamesToKill.end())
2198             tmp.push_back(*it2);
2199         }
2200       if(!tmp.empty())
2201         (*it).second=tmp;
2202       else
2203         tmp.push_back((*it).first);
2204     }
2205   for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
2206     _groups.erase(*it);
2207 }
2208
2209 void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
2210 {
2211   std::vector<int> levs=getNonEmptyLevels();
2212   if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
2213     throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
2214   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
2215   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
2216   int nbNodes=m0->getNumberOfNodes();
2217   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
2218   DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
2219   m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
2220   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
2221   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
2222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
2223   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
2224   // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
2225   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
2226   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
2227   descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
2228   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
2229   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
2230   DataArrayInt *cellsInM1ToRenumW4Tmp=0;
2231   m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
2232   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
2233   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
2234   cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
2235   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
2236   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
2237   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
2238   m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
2239   m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
2240   // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
2241   tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
2242   m0->setCoords(tmp0->getCoords());
2243   m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
2244   m1->setCoords(m0->getCoords());
2245   _coords=m0->getCoords(); _coords->incrRef();
2246   // duplication of cells in group 'grpNameM1' on level -1
2247   m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
2248   std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
2249   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
2250   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
2251   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
2252   //
2253   newm1->setName(getName());
2254   const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
2255   if(!fam)
2256     throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
2257   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
2258   newFam->alloc(newm1->getNumberOfCells(),1);
2259   int idd=getMaxFamilyId()+1;
2260   int globStart=0,start=0,end,globEnd;
2261   int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
2262   for(int i=0;i<nbOfChunks;i++)
2263     {
2264       globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
2265       if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
2266         {
2267           end=start+szOfCellGrpOfSameType->getIJ(i,0);
2268           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
2269           newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
2270           start=end;
2271         }
2272       else
2273         {
2274           newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
2275         }
2276       globStart=globEnd;
2277     }
2278   newm1->setCoords(getCoords());
2279   setMeshAtLevel(-1,newm1);
2280   setFamilyFieldArr(-1,newFam);
2281   std::string grpName2(grpNameM1); grpName2+="_dup";
2282   addFamily(grpName2.c_str(),idd);
2283   addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
2284   //
2285   fam=_fam_coords;
2286   if(fam)
2287     {
2288       int newNbOfNodes=getCoords()->getNumberOfTuples();
2289       newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
2290       newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
2291       newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
2292       _fam_coords=newFam;
2293     }
2294   nodesDuplicated=nodeIdsToDuplicate.retn();
2295   cellsModified=cellsToModifyConn0.retn();
2296   cellsNotModified=cellsToModifyConn1.retn();
2297 }
2298
2299 /*!
2300  * \param [out] oldCode retrieves the distribution of types before the call if true is returned
2301  * \param [out] newCode etrieves the distribution of types after the call if true is returned
2302  * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
2303  * 
2304  * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering.
2305  * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered.
2306  */
2307 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
2308 {
2309   o2nRenumCell=0; oldCode.clear(); newCode.clear();
2310   std::vector<int> levs=getNonEmptyLevels();
2311   bool ret=false;
2312   std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
2313   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
2314   int start=0;
2315   int end=0;
2316   for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
2317     {
2318       MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
2319       std::vector<int> code1=m->getDistributionOfTypes();
2320       end=PutInThirdComponentOfCodeOffset(code1,start);
2321       oldCode.insert(oldCode.end(),code1.begin(),code1.end());
2322       bool hasChanged=m->unPolyze();
2323       DataArrayInt *fake=0;
2324       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
2325                                                                                            MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
2326       fake->decrRef();
2327       renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
2328       if(hasChanged)
2329         {
2330           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
2331           m->renumberCells(o2nCellsPart2->getConstPointer(),false);
2332           ret=true;
2333           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
2334           const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
2335           const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
2336           setMeshAtLevel(*it,m);
2337           std::vector<int> code2=m->getDistributionOfTypes();
2338           end=PutInThirdComponentOfCodeOffset(code2,start);
2339           newCode.insert(newCode.end(),code2.begin(),code2.end());
2340           //
2341           if(o2nCellsPart2->isIdentity())
2342             continue;
2343           if(famField)
2344             {
2345               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
2346               setFamilyFieldArr(*it,newFamField);
2347             }
2348           if(numField)
2349             {
2350               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
2351               setRenumFieldArr(*it,newNumField);
2352             }
2353         }
2354       else
2355         {
2356           newCode.insert(newCode.end(),code1.begin(),code1.end());
2357         }
2358       start=end;
2359     }
2360   if(ret)
2361     {
2362       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
2363       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
2364       o2nRenumCell=o2nRenumCellRet.retn();
2365     }
2366   return ret;
2367 }
2368
2369 struct MEDLoaderAccVisit1
2370 {
2371   MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
2372   int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
2373   int _new_nb_of_nodes;
2374 };
2375
2376 /*!
2377  * 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.
2378  * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
2379  * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
2380  * -1 values in returned array means that the corresponding old node is no more used.
2381  *
2382  * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched NULL pointer is returned and nothing
2383  *         is modified in \a this.
2384  * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
2385  *  set coordinates.
2386  */
2387 DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
2388 {
2389   const DataArrayDouble *coo=getCoords();
2390   if(!coo)
2391     throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
2392   int nbOfNodes=coo->getNumberOfTuples();
2393   std::vector<bool> nodeIdsInUse(nbOfNodes,false);
2394   std::vector<int> neLevs=getNonEmptyLevels();
2395   for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
2396     {
2397       MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
2398       m->computeNodeIdsAlg(nodeIdsInUse);
2399     }
2400   int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
2401   if(nbrOfNodesInUse==nbOfNodes)
2402     return 0;
2403   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
2404   std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
2405   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
2406   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
2407   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
2408   if((const DataArrayInt *)_fam_coords)
2409     newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
2410   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
2411   if((const DataArrayInt *)_num_coords)
2412     newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
2413   _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _rev_num_coords=0;
2414   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2415     {
2416       if((MEDFileUMeshSplitL1*)*it)
2417         (*it)->renumberNodesInConn(ret->begin());
2418     }
2419   return ret.retn();
2420 }
2421
2422 /*!
2423  * This method is here only to add a group on node.
2424  * MEDFileUMesh::setGroupsAtLevel with 1 in the first parameter.
2425  *
2426  * \param [in] ids node ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
2427  */
2428 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
2429 {
2430   const DataArrayDouble *coords=_coords;
2431   if(!coords)
2432     throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
2433   int nbOfNodes=coords->getNumberOfTuples();
2434   if(!((DataArrayInt *)_fam_coords))
2435     { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
2436   //
2437   addGroupUnderground(ids,_fam_coords);
2438 }
2439
2440 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
2441 {
2442   std::vector<int> levs=getNonEmptyLevelsExt();
2443   if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
2444     { 
2445       std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
2446       std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
2447     }
2448   if(meshDimRelToMaxExt==1)
2449     { addNodeGroup(ids); return ; }
2450   MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
2451   DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
2452   addGroupUnderground(ids,fam);
2453 }
2454
2455 /*!
2456  * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
2457  * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not NULL (no check of that will be performed)
2458  */
2459 void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
2460 {
2461   if(!ids)
2462     throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
2463   std::string grpName(ids->getName());
2464   if(grpName.empty())
2465     throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
2466   ids->checkStrictlyMonotonic(true);
2467   famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
2468   std::vector<std::string> grpsNames=getGroupsNames();
2469   if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
2470     {
2471       std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
2472       throw INTERP_KERNEL::Exception(oss.str().c_str());
2473     }
2474   std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
2475   allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
2476   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
2477   std::set<int> diffFamIds=famIds->getDifferentValues();
2478   std::vector<int> familyIds;
2479   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
2480   int maxVal=getTheMaxFamilyId()+1;
2481   std::map<std::string,int> families(_families);
2482   std::map<std::string, std::vector<std::string> > groups(_groups);
2483   std::vector<std::string> fams;
2484   bool created(false);
2485   for(std::set<int>::const_iterator famId=diffFamIds.begin();famId!=diffFamIds.end();famId++)
2486     {
2487       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
2488       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
2489       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
2490       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
2491       if(ret0->empty())
2492         {
2493           bool isFamPresent=false;
2494           for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
2495             isFamPresent=(*itl)->presenceOfValue(*famId);
2496           if(!isFamPresent)
2497             { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
2498           else
2499             {
2500               familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ids2); std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,maxVal,created);
2501               fams.push_back(locFamName);
2502               if(existsFamily(*famId))
2503                 {
2504                   std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
2505                   ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
2506                 }
2507               maxVal++;
2508             } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
2509         }
2510       else
2511         {
2512           familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
2513           familyIds.push_back(maxVal+1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
2514           std::string n2(FindOrCreateAndGiveFamilyWithId(families,maxVal+1,created)); fams.push_back(n2);
2515           if(existsFamily(*famId))
2516             {
2517               std::string n1(FindOrCreateAndGiveFamilyWithId(families,maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
2518               ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
2519             }
2520           maxVal+=2;
2521         }
2522     }
2523   for(std::size_t i=0;i<familyIds.size();i++)
2524     {
2525       DataArrayInt *da=idsPerfamiliyIds[i];
2526       famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
2527     }
2528   _families=families;
2529   _groups=groups;
2530   _groups[grpName]=fams;
2531 }
2532
2533 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
2534 {
2535   std::string oldName=getFamilyNameGivenId(id);
2536   _families.erase(oldName);
2537   _families[newFamName]=id;
2538 }
2539
2540 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
2541 {
2542   std::vector<int> levSet=getNonEmptyLevels();
2543   std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
2544   if(it==levSet.end())
2545     throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
2546   int pos=(-meshDimRelToMax);
2547   _ms[pos]=0;
2548 }
2549
2550 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
2551 {
2552   setMeshAtLevelGen(meshDimRelToMax,m,newOrOld);
2553 }
2554
2555 void MEDFileUMesh::setMeshAtLevelGen(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
2556 {
2557   dealWithTinyInfo(m);
2558   std::vector<int> levSet=getNonEmptyLevels();
2559   if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
2560     {
2561       if((DataArrayDouble *)_coords==0)
2562         {
2563           DataArrayDouble *c=m->getCoords();
2564           if(c)
2565             c->incrRef();
2566           _coords=c;
2567         }
2568       if(m->getCoords()!=_coords)
2569         throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
2570       int sz=(-meshDimRelToMax)+1;
2571       if(sz>=(int)_ms.size())
2572         _ms.resize(sz);
2573       checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
2574       _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
2575     }
2576   else
2577     _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
2578 }
2579
2580 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms) throw(INTERP_KERNEL::Exception)
2581 {
2582   if(ms.empty())
2583     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
2584   int sz=(-meshDimRelToMax)+1;
2585   if(sz>=(int)_ms.size())
2586     _ms.resize(sz);
2587   checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
2588   DataArrayDouble *coo=checkMultiMesh(ms);
2589   if((DataArrayDouble *)_coords==0)
2590     {
2591       coo->incrRef();
2592       _coords=coo;
2593     }
2594   else
2595     if((DataArrayDouble *)_coords!=coo)
2596       throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
2597   std::vector<DataArrayInt *> corr;
2598   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
2599   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
2600   setMeshAtLevel(meshDimRelToMax,m);
2601   std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
2602   setGroupsAtLevel(meshDimRelToMax,corr2,true);
2603 }
2604
2605 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
2606 {
2607   if(ms.empty())
2608     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
2609   int sz=(-meshDimRelToMax)+1;
2610   if(sz>=(int)_ms.size())
2611     _ms.resize(sz);
2612   checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
2613   DataArrayDouble *coo=checkMultiMesh(ms);
2614   if((DataArrayDouble *)_coords==0)
2615     {
2616       coo->incrRef();
2617       _coords=coo;
2618     }
2619   else
2620     if((DataArrayDouble *)_coords!=coo)
2621       throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
2622   MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
2623   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
2624   int i=0;
2625   for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
2626     {
2627       DataArrayInt *arr=0;
2628       bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
2629       corr[i]=arr;
2630       if(!test)
2631         {
2632           std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
2633           throw INTERP_KERNEL::Exception(oss.str().c_str());
2634         }
2635     }
2636   std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
2637   setGroupsAtLevel(meshDimRelToMax,corr2,renum);
2638 }
2639
2640 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
2641 {
2642   const DataArrayDouble *ret=ms[0]->getCoords();
2643   int mdim=ms[0]->getMeshDimension();
2644   for(unsigned int i=1;i<ms.size();i++)
2645     {
2646       ms[i]->checkCoherency();
2647       if(ms[i]->getCoords()!=ret)
2648         throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
2649       if(ms[i]->getMeshDimension()!=mdim)
2650         throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
2651     }
2652   return const_cast<DataArrayDouble *>(ret);
2653 }
2654
2655 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
2656 {
2657   if(meshDimRelToMaxExt==1)
2658     {
2659       if(!famArr)
2660         {
2661           _fam_coords=0;
2662           return ;
2663         }
2664       DataArrayDouble *coo(_coords);
2665       if(!coo)
2666         throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
2667       famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
2668       famArr->incrRef();
2669       _fam_coords=famArr;
2670       return ;
2671     }
2672   if(meshDimRelToMaxExt>1)
2673     throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
2674   int traducedRk=-meshDimRelToMaxExt;
2675   if(traducedRk>=(int)_ms.size())
2676     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2677   if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
2678     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2679   return _ms[traducedRk]->setFamilyArr(famArr);
2680 }
2681
2682 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
2683 {
2684   if(meshDimRelToMaxExt==1)
2685     {
2686       if(!renumArr)
2687         {
2688           _num_coords=0;
2689           _rev_num_coords=0;
2690           return ;
2691         }
2692       DataArrayDouble *coo(_coords);
2693       if(!coo)
2694         throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
2695       renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
2696       renumArr->incrRef();
2697       _num_coords=renumArr;
2698       computeRevNum();
2699       return ;
2700     }
2701   if(meshDimRelToMaxExt>1)
2702     throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
2703   int traducedRk=-meshDimRelToMaxExt;
2704   if(traducedRk>=(int)_ms.size())
2705     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2706   if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
2707     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2708   return _ms[traducedRk]->setRenumArr(renumArr);
2709 }
2710
2711 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
2712 {
2713   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2714     if((const MEDFileUMeshSplitL1 *)(*it))
2715       (*it)->synchronizeTinyInfo(*this);
2716 }
2717
2718 /*!
2719  * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
2720  */
2721 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
2722 {
2723   DataArrayInt *arr=_fam_coords;
2724   if(arr)
2725     arr->changeValue(oldId,newId);
2726   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2727     {
2728       MEDFileUMeshSplitL1 *sp=(*it);
2729       if(sp)
2730         {
2731           sp->changeFamilyIdArr(oldId,newId);
2732         }
2733     }
2734 }
2735
2736 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
2737 {
2738   std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
2739   const DataArrayInt *da(_fam_coords);
2740   if(da)
2741     { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
2742   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2743     {
2744       const MEDFileUMeshSplitL1 *elt(*it);
2745       if(elt)
2746         {
2747           da=elt->getFamilyField();
2748           if(da)
2749             { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
2750         }
2751     }
2752   return ret;
2753 }
2754
2755 void MEDFileUMesh::computeRevNum() const
2756 {
2757   if((const DataArrayInt *)_num_coords)
2758     {
2759       int pos;
2760       int maxValue=_num_coords->getMaxValue(pos);
2761       _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
2762     }
2763 }
2764
2765 std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
2766 {
2767   std::size_t ret=MEDFileMesh::getHeapMemorySize();
2768   if((const DataArrayInt*)_fam_nodes)
2769     ret+=_fam_nodes->getHeapMemorySize();
2770   if((const DataArrayInt*)_num_nodes)
2771     ret+=_num_nodes->getHeapMemorySize();
2772   if((const DataArrayInt*)_fam_cells)
2773     ret+=_fam_cells->getHeapMemorySize();
2774   if((const DataArrayInt*)_num_cells)
2775     ret+=_num_cells->getHeapMemorySize();
2776   if((const DataArrayInt*)_rev_num_nodes)
2777     ret+=_rev_num_nodes->getHeapMemorySize();
2778   if((const DataArrayInt*)_rev_num_cells)
2779     ret+=_rev_num_cells->getHeapMemorySize();
2780   return ret;
2781 }
2782
2783 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2784 {
2785   int ret=-std::numeric_limits<int>::max(),tmp=-1;
2786   if((const DataArrayInt *)_fam_nodes)
2787     {
2788       int val=_fam_nodes->getMaxValue(tmp);
2789       ret=std::max(ret,val);
2790     }
2791   if((const DataArrayInt *)_fam_cells)
2792     {
2793       int val=_fam_cells->getMaxValue(tmp);
2794       ret=std::max(ret,val);
2795     }
2796   return ret;
2797 }
2798
2799 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2800 {
2801   int ret=std::numeric_limits<int>::max(),tmp=-1;
2802   if((const DataArrayInt *)_fam_nodes)
2803     {
2804       int val=_fam_nodes->getMinValue(tmp);
2805       ret=std::min(ret,val);
2806     }
2807   if((const DataArrayInt *)_fam_cells)
2808     {
2809       int val=_fam_cells->getMinValue(tmp);
2810       ret=std::min(ret,val);
2811     }
2812   return ret;
2813 }
2814
2815 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2816 {
2817   if(!MEDFileMesh::isEqual(other,eps,what))
2818     return false;
2819   const MEDFileStructuredMesh *otherC=dynamic_cast<const  MEDFileStructuredMesh *>(other);
2820   if(!otherC)
2821     {
2822       what="Mesh types differ ! This is structured and other is NOT !";
2823       return false;
2824     }
2825   const DataArrayInt *famc1=_fam_nodes;
2826   const DataArrayInt *famc2=otherC->_fam_nodes;
2827   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2828     {
2829       what="Mismatch of families arr on nodes ! One is defined and not other !";
2830       return false;
2831     }
2832   if(famc1)
2833     {
2834       bool ret=famc1->isEqual(*famc2);
2835       if(!ret)
2836         {
2837           what="Families arr on nodes differ !";
2838           return false;
2839         }
2840     }
2841   famc1=_fam_cells;
2842   famc2=otherC->_fam_cells;
2843   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2844     {
2845       what="Mismatch of families arr on cells ! One is defined and not other !";
2846       return false;
2847     }
2848   if(famc1)
2849     {
2850       bool ret=famc1->isEqual(*famc2);
2851       if(!ret)
2852         {
2853           what="Families arr on cells differ !";
2854           return false;
2855         }
2856     }
2857   famc1=_num_nodes;
2858   famc2=otherC->_num_nodes;
2859   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2860     {
2861       what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2862       return false;
2863     }
2864   if(famc1)
2865     {
2866       bool ret=famc1->isEqual(*famc2);
2867       if(!ret)
2868         {
2869           what="Numbering arr on nodes differ !";
2870           return false;
2871         }
2872     }
2873   famc1=_num_cells;
2874   famc2=otherC->_num_cells;
2875   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2876     {
2877       what="Mismatch of numbering arr on cells ! One is defined and not other !";
2878       return false;
2879     }
2880   if(famc1)
2881     {
2882       bool ret=famc1->isEqual(*famc2);
2883       if(!ret)
2884         {
2885           what="Numbering arr on cells differ !";
2886           return false;
2887         }
2888     }
2889   return true;
2890 }
2891
2892 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
2893 {
2894   MEDFileMesh::clearNonDiscrAttributes();
2895   const DataArrayInt *tmp=_fam_nodes;
2896   if(tmp)
2897     (const_cast<DataArrayInt *>(tmp))->setName("");
2898   tmp=_num_nodes;
2899   if(tmp)
2900     (const_cast<DataArrayInt *>(tmp))->setName("");
2901   tmp=_fam_cells;
2902   if(tmp)
2903     (const_cast<DataArrayInt *>(tmp))->setName("");
2904   tmp=_num_cells;
2905   if(tmp)
2906     (const_cast<DataArrayInt *>(tmp))->setName("");
2907 }
2908
2909 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2910 {
2911   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
2912     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
2913   std::vector<int> famIds=getFamiliesIds(fams);
2914   if(meshDimRelToMaxExt==1)
2915     {
2916       if((const DataArrayInt *)_fam_nodes)
2917         {
2918           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2919           if(!famIds.empty())
2920             da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2921           else
2922             da=_fam_nodes->getIdsEqualList(0,0);
2923           if(renum)
2924             return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
2925           else
2926             return da.retn();
2927         }
2928       else
2929         throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
2930     }
2931   else
2932     {
2933       if((const DataArrayInt *)_fam_cells)
2934         {
2935           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2936           if(!famIds.empty())
2937             da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2938           else
2939             da=_fam_cells->getIdsEqualList(0,0);
2940           if(renum)
2941             return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
2942           else
2943             return da.retn();
2944         }
2945       else
2946         throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
2947     }
2948 }
2949
2950 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
2951 {
2952   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
2953     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
2954   const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
2955   if(!mesh)
2956     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
2957   if(meshDimRelToMaxExt==0)
2958     {
2959       int nbCells=mesh->getNumberOfCells();
2960       famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
2961       _fam_cells=famArr;
2962     }
2963   else
2964     {
2965       int nbNodes=mesh->getNumberOfNodes();
2966       famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
2967       _fam_nodes=famArr;
2968     }
2969   if(famArr)
2970     famArr->incrRef();
2971 }
2972
2973 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
2974 {
2975   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
2976     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
2977   const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
2978   if(!mesh)
2979     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
2980   if(meshDimRelToMaxExt==0)
2981     {
2982       int nbCells=mesh->getNumberOfCells();
2983       renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
2984       _num_cells=renumArr;
2985     }
2986   else
2987     {
2988       int nbNodes=mesh->getNumberOfNodes();
2989       renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
2990       _num_nodes=renumArr;
2991     }
2992   if(renumArr)
2993     renumArr->incrRef();
2994 }
2995
2996 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2997 {
2998   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
2999     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
3000   if(meshDimRelToMaxExt==0)
3001     return _fam_cells;
3002   else
3003     return _fam_nodes;
3004 }
3005
3006 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3007 {
3008   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3009     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
3010   if(meshDimRelToMaxExt==0)
3011     return _num_cells;
3012   else
3013     return _num_nodes;
3014 }
3015
3016 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3017 {
3018   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3019     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
3020   if(meshDimRelToMaxExt==0)
3021     {
3022       if((const DataArrayInt *)_num_cells)
3023         {
3024           int pos;
3025           int maxValue=_num_cells->getMaxValue(pos);
3026           _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
3027           return _rev_num_cells;
3028         }
3029       else
3030         throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
3031     }
3032   else
3033     {
3034       if((const DataArrayInt *)_num_nodes)
3035         {
3036           int pos;
3037           int maxValue=_num_nodes->getMaxValue(pos);
3038           _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
3039           return _rev_num_nodes;
3040         }
3041       else
3042         throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
3043     }
3044 }
3045
3046 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
3047 {
3048   std::vector<int> ret(1);
3049   return ret;
3050 }
3051
3052 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
3053 {
3054   std::vector<int> ret(2);
3055   ret[0]=1;
3056   return ret;
3057 }
3058
3059 /*!
3060  * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
3061  */
3062 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
3063 {
3064   oldCode.clear(); newCode.clear(); o2nRenumCell=0;
3065   return false;
3066 }
3067
3068 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3069 {
3070   DataArrayInt *arr=_fam_nodes;
3071   if(arr)
3072     arr->changeValue(oldId,newId);
3073   arr=_fam_cells;
3074   if(arr)
3075     arr->changeValue(oldId,newId);
3076 }
3077
3078 void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
3079 {
3080   if((const DataArrayInt*)_fam_nodes)
3081     _fam_nodes=_fam_nodes->deepCpy();
3082   if((const DataArrayInt*)_num_nodes)
3083     _num_nodes=_num_nodes->deepCpy();
3084   if((const DataArrayInt*)_fam_cells)
3085     _fam_cells=_fam_cells->deepCpy();
3086   if((const DataArrayInt*)_num_cells)
3087     _num_cells=_num_cells->deepCpy();
3088   if((const DataArrayInt*)_rev_num_nodes)
3089     _rev_num_nodes=_rev_num_nodes->deepCpy();
3090   if((const DataArrayInt*)_rev_num_cells)
3091     _rev_num_cells=_rev_num_cells->deepCpy();
3092 }
3093
3094 /*!
3095  * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
3096  * 
3097  * \return a pointer to cartesian mesh that need to be managed by the caller.
3098  * \warning the returned pointer has to be managed by the caller.
3099  */
3100 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
3101 {
3102   if(renum)
3103     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
3104   if(meshDimRelToMax!=0)
3105     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
3106   const MEDCouplingStructuredMesh *m=getStructuredMesh();
3107   if(m)
3108     m->incrRef();
3109   return const_cast<MEDCouplingStructuredMesh *>(m);
3110 }
3111
3112 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3113 {
3114   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3115     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
3116   const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
3117   if(!cmesh)
3118     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
3119   if(meshDimRelToMaxExt==0)
3120     return cmesh->getNumberOfCells();
3121   else
3122     return cmesh->getNumberOfNodes();
3123 }
3124
3125 int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
3126 {
3127   const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
3128   if(!cmesh)
3129     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
3130   return cmesh->getNumberOfNodes();
3131 }
3132
3133 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
3134 {
3135   med_geometry_type geoTypeReq=MED_NONE;
3136   switch(meshDim)
3137     {
3138     case 3:
3139       geoTypeReq=MED_HEXA8;
3140       break;
3141     case 2:
3142       geoTypeReq=MED_QUAD4;
3143       break;
3144     case 1:
3145       geoTypeReq=MED_SEG2;
3146       break;
3147     case 0:
3148       geoTypeReq=MED_POINT1;
3149       break;
3150     default:
3151       throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
3152     }
3153   return geoTypeReq;
3154 }
3155
3156 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3157 {
3158   setName(strm->getName());
3159   setDescription(strm->getDescription());
3160   setIteration(strm->getIteration());
3161   setOrder(strm->getOrder());
3162   setTimeValue(strm->getTime());
3163   setTimeUnit(strm->getTimeUnit());
3164   MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups);
3165   med_bool chgt=MED_FALSE,trsf=MED_FALSE;
3166   int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
3167   if(nbOfElt>0)
3168     {
3169       _fam_nodes=DataArrayInt::New();
3170       _fam_nodes->alloc(nbOfElt,1);
3171       MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
3172     }
3173   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
3174   if(nbOfElt>0)
3175     {
3176       _num_nodes=DataArrayInt::New();
3177       _num_nodes->alloc(nbOfElt,1);
3178       MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
3179     }
3180   int meshDim=getStructuredMesh()->getMeshDimension();
3181   med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
3182   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
3183   if(nbOfElt>0)
3184     {
3185       _fam_cells=DataArrayInt::New();
3186       _fam_cells->alloc(nbOfElt,1);
3187       MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
3188     }
3189   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
3190   if(nbOfElt>0)
3191     {
3192       _num_cells=DataArrayInt::New();
3193       _num_cells->alloc(nbOfElt,1);
3194       MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
3195     }
3196 }
3197
3198 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
3199 {
3200   int meshDim=getStructuredMesh()->getMeshDimension();
3201   med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
3202   //
3203   if((const DataArrayInt *)_fam_cells)
3204     MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
3205   if((const DataArrayInt *)_fam_nodes)
3206     MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
3207   if((const DataArrayInt *)_num_cells)
3208     MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
3209   if((const DataArrayInt *)_num_nodes)
3210     MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
3211   //
3212   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
3213 }
3214
3215 MEDFileCMesh *MEDFileCMesh::New()
3216 {
3217   return new MEDFileCMesh;
3218 }
3219
3220 MEDFileCMesh *MEDFileCMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
3221 {
3222   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
3223   if(ms.empty())
3224     {
3225       std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
3226       throw INTERP_KERNEL::Exception(oss.str().c_str());
3227     }
3228   MEDFileUtilities::CheckFileForRead(fileName);
3229   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3230   int dt,it;
3231   ParaMEDMEM::MEDCouplingMeshType meshType;
3232   std::string dummy2;
3233   MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
3234   return new MEDFileCMesh(fid,ms.front().c_str(),dt,it);
3235 }
3236
3237 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3238 {
3239   MEDFileUtilities::CheckFileForRead(fileName);
3240   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3241   return new MEDFileCMesh(fid,mName,dt,it);
3242 }
3243
3244 std::size_t MEDFileCMesh::getHeapMemorySize() const
3245 {
3246   std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
3247   if((const MEDCouplingCMesh *)_cmesh)
3248     ret+=_cmesh->getHeapMemorySize();
3249   return ret;
3250 }
3251
3252 int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
3253 {
3254   if(!((const MEDCouplingCMesh*)_cmesh))
3255     throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
3256   return _cmesh->getMeshDimension();
3257 }
3258
3259 std::string MEDFileCMesh::simpleRepr() const
3260 {
3261   return MEDFileStructuredMesh::simpleRepr();
3262 }
3263
3264 std::string MEDFileCMesh::advancedRepr() const
3265 {
3266   return simpleRepr();
3267 }
3268
3269 MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
3270 {
3271   MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
3272   return ret.retn();
3273 }
3274
3275 MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
3276 {
3277   MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
3278   if((const MEDCouplingCMesh*)_cmesh)
3279     ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
3280   ret->deepCpyAttributes();
3281   return ret.retn();
3282 }
3283
3284 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3285 {
3286   if(!MEDFileStructuredMesh::isEqual(other,eps,what))
3287     return false;
3288   const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
3289   if(!otherC)
3290     {
3291       what="Mesh types differ ! This is cartesian and other is NOT !";
3292       return false;
3293     }
3294   clearNonDiscrAttributes();
3295   otherC->clearNonDiscrAttributes();
3296   const MEDCouplingCMesh *coo1=_cmesh;
3297   const MEDCouplingCMesh *coo2=otherC->_cmesh;
3298   if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
3299     {
3300       what="Mismatch of cartesian meshes ! One is defined and not other !";
3301       return false;
3302     }
3303   if(coo1)
3304     {
3305       bool ret=coo1->isEqual(coo2,eps);
3306       if(!ret)
3307         {
3308           what="cartesian meshes differ !";
3309           return false;
3310         }
3311     }
3312   return true;
3313 }
3314
3315 void MEDFileCMesh::clearNonDiscrAttributes() const
3316 {
3317   MEDFileStructuredMesh::clearNonDiscrAttributes();
3318   MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
3319 }
3320
3321 MEDFileCMesh::MEDFileCMesh()
3322 {
3323 }
3324
3325 MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3326 try
3327   {
3328     loadCMeshFromFile(fid,mName,dt,it);
3329   }
3330 catch(INTERP_KERNEL::Exception& e)
3331   {
3332     throw e;
3333   }
3334
3335 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3336 {
3337   ParaMEDMEM::MEDCouplingMeshType meshType;
3338   int dummy0,dummy1;
3339   std::string dtunit;
3340   int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
3341   if(meshType!=CARTESIAN)
3342     {
3343       std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
3344       throw INTERP_KERNEL::Exception(oss.str().c_str());
3345     }
3346   MEDFileCMeshL2 loaderl2;
3347   loaderl2.loadAll(fid,mid,mName,dt,it);
3348   MEDCouplingCMesh *mesh=loaderl2.getMesh();
3349   mesh->incrRef();
3350   _cmesh=mesh;
3351   loadStrMeshFromFile(&loaderl2,fid,mName,dt,it);
3352 }
3353
3354 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
3355 {
3356   synchronizeTinyInfoOnLeaves();
3357   return _cmesh;
3358 }
3359
3360 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
3361 {
3362   synchronizeTinyInfoOnLeaves();
3363   return _cmesh;
3364 }
3365
3366 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
3367 {
3368   dealWithTinyInfo(m);
3369   if(m)
3370     m->incrRef();
3371   _cmesh=m;
3372 }
3373
3374 void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
3375 {
3376   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3377   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3378   INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
3379   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3380   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3381   MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
3382   int spaceDim=_cmesh->getSpaceDimension();
3383   int meshDim=_cmesh->getMeshDimension();
3384   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3385   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3386   for(int i=0;i<spaceDim;i++)
3387     {
3388       std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
3389       std::string c,u;
3390       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3391       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
3392       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
3393     }
3394   MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
3395   MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
3396   for(int i=0;i<spaceDim;i++)
3397     {
3398       const DataArrayDouble *da=_cmesh->getCoordsAt(i);
3399       MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
3400     }
3401   //
3402   MEDFileStructuredMesh::writeStructuredLL(fid,maa);
3403 }
3404
3405 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
3406 {
3407   const MEDCouplingCMesh *cmesh=_cmesh;
3408   if(!cmesh)
3409     return;
3410   (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
3411   (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
3412   (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
3413   (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
3414 }
3415
3416 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
3417 {
3418   return new MEDFileCurveLinearMesh;
3419 }
3420
3421 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
3422 {
3423   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
3424   if(ms.empty())
3425     {
3426       std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
3427       throw INTERP_KERNEL::Exception(oss.str().c_str());
3428     }
3429   MEDFileUtilities::CheckFileForRead(fileName);
3430   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3431   int dt,it;
3432   ParaMEDMEM::MEDCouplingMeshType meshType;
3433   std::string dummy2;
3434   MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
3435   return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it);
3436 }
3437
3438 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3439 {
3440   MEDFileUtilities::CheckFileForRead(fileName);
3441   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3442   return new MEDFileCurveLinearMesh(fid,mName,dt,it);
3443 }
3444
3445 std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
3446 {
3447   std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
3448   if((const MEDCouplingCurveLinearMesh *)_clmesh)
3449     ret+=_clmesh->getHeapMemorySize();
3450   return ret;
3451 }
3452
3453 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
3454 {
3455   MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
3456   return ret.retn();
3457 }
3458
3459 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
3460 {
3461   MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
3462   if((const MEDCouplingCurveLinearMesh*)_clmesh)
3463     ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
3464   ret->deepCpyAttributes();
3465   return ret.retn();
3466 }
3467
3468 int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
3469 {
3470   if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
3471     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
3472   return _clmesh->getMeshDimension();
3473 }
3474
3475 std::string MEDFileCurveLinearMesh::simpleRepr() const
3476 {
3477   return MEDFileStructuredMesh::simpleRepr();
3478 }
3479
3480 std::string MEDFileCurveLinearMesh::advancedRepr() const
3481 {
3482   return simpleRepr();
3483 }
3484
3485 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3486 {
3487   if(!MEDFileStructuredMesh::isEqual(other,eps,what))
3488     return false;
3489   const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
3490   if(!otherC)
3491     {
3492       what="Mesh types differ ! This is curve linear and other is NOT !";
3493       return false;
3494     }
3495   clearNonDiscrAttributes();
3496   otherC->clearNonDiscrAttributes();
3497   const MEDCouplingCurveLinearMesh *coo1=_clmesh;
3498   const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
3499   if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
3500     {
3501       what="Mismatch of curve linear meshes ! One is defined and not other !";
3502       return false;
3503     }
3504   if(coo1)
3505     {
3506       bool ret=coo1->isEqual(coo2,eps);
3507       if(!ret)
3508         {
3509           what="curve linear meshes differ !";
3510           return false;
3511         }
3512     }
3513   return true;
3514 }
3515
3516 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
3517 {
3518   MEDFileStructuredMesh::clearNonDiscrAttributes();
3519   MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
3520 }
3521
3522 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
3523 {
3524   const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
3525   if(!clmesh)
3526     return;
3527   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
3528   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
3529   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
3530   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
3531 }
3532
3533 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
3534 {
3535   synchronizeTinyInfoOnLeaves();
3536   return _clmesh;
3537 }
3538
3539 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
3540 {
3541   dealWithTinyInfo(m);
3542   if(m)
3543     m->incrRef();
3544   _clmesh=m;
3545 }
3546
3547 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
3548 {
3549   synchronizeTinyInfoOnLeaves();
3550   return _clmesh;
3551 }
3552
3553 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
3554 {
3555 }
3556
3557 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3558 try
3559   {
3560     loadCLMeshFromFile(fid,mName,dt,it);
3561   }
3562 catch(INTERP_KERNEL::Exception& e)
3563   {
3564     throw e;
3565   }
3566
3567 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
3568 {
3569   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3570   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3571   INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
3572   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3573   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3574   MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
3575   int spaceDim=_clmesh->getSpaceDimension();
3576   int meshDim=_clmesh->getMeshDimension();
3577   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3578   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3579   const DataArrayDouble *coords=_clmesh->getCoords();
3580   if(!coords)
3581     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
3582   for(int i=0;i<spaceDim;i++)
3583     {
3584       std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
3585       std::string c,u;
3586       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3587       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
3588       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
3589     }
3590   MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
3591   MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
3592   std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
3593   MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
3594   
3595   MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
3596   //
3597   MEDFileStructuredMesh::writeStructuredLL(fid,maa);
3598 }
3599
3600 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3601 {
3602   ParaMEDMEM::MEDCouplingMeshType meshType;
3603   int dummy0,dummy1;
3604   std::string dtunit;
3605   int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
3606   if(meshType!=CURVE_LINEAR)
3607     {
3608       std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
3609       throw INTERP_KERNEL::Exception(oss.str().c_str());
3610     }
3611   MEDFileCLMeshL2 loaderl2;
3612   loaderl2.loadAll(fid,mid,mName,dt,it);
3613   MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
3614   mesh->incrRef();
3615   _clmesh=mesh;
3616   loadStrMeshFromFile(&loaderl2,fid,mName,dt,it);
3617 }
3618
3619 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
3620 {
3621   return new MEDFileMeshMultiTS;
3622 }
3623
3624 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
3625 {
3626   return new MEDFileMeshMultiTS(fileName);
3627 }
3628
3629 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
3630 {
3631   return new MEDFileMeshMultiTS(fileName,mName);
3632 }
3633
3634 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
3635 {
3636   MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
3637   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
3638   std::size_t i=0;
3639   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
3640     if((const MEDFileMesh *)*it)
3641       meshOneTs[i]=(*it)->deepCpy();
3642   ret->_mesh_one_ts=meshOneTs;
3643   return ret.retn();
3644 }
3645
3646 std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
3647 {
3648   std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
3649   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
3650     ret+=(*it)->getHeapMemorySize();
3651   return ret;
3652 }
3653
3654 const char *MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
3655 {
3656   if(_mesh_one_ts.empty())
3657     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
3658   return _mesh_one_ts[0]->getName();
3659 }
3660
3661 void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
3662 {
3663   std::string oldName(getName());
3664   std::vector< std::pair<std::string,std::string> > v(1);
3665   v[0].first=oldName; v[0].second=newMeshName;
3666   changeNames(v);
3667 }
3668
3669 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
3670 {
3671   bool ret=false;
3672   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
3673     {
3674       MEDFileMesh *cur(*it);
3675       if(cur)
3676         ret=cur->changeNames(modifTab) || ret;
3677     }
3678   return ret;
3679 }
3680
3681 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
3682 {
3683   if(_mesh_one_ts.empty())
3684     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
3685   return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
3686 }
3687
3688 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
3689 {
3690   if(!mesh1TimeStep)
3691     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
3692   _mesh_one_ts.resize(1);
3693   mesh1TimeStep->incrRef();
3694   //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
3695   _mesh_one_ts[0]=mesh1TimeStep;
3696 }
3697
3698 void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
3699 {
3700   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
3701     {
3702       (*it)->copyOptionsFrom(*this);
3703       (*it)->write(fid);
3704     }
3705 }
3706
3707 void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
3708 {
3709   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
3710   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
3711   std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
3712   MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
3713   write(fid);
3714 }
3715
3716 void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
3717 {//for the moment to be improved
3718   _mesh_one_ts.resize(1);
3719   _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
3720 }
3721
3722 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
3723 {
3724 }
3725
3726 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
3727 try
3728   {
3729     std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
3730     if(ms.empty())
3731     {
3732       std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
3733       throw INTERP_KERNEL::Exception(oss.str().c_str());
3734     }
3735     MEDFileUtilities::CheckFileForRead(fileName);
3736     MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3737     int dt,it;
3738     ParaMEDMEM::MEDCouplingMeshType meshType;
3739     std::string dummy2;
3740     MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
3741     loadFromFile(fileName,ms.front().c_str());
3742   }
3743 catch(INTERP_KERNEL::Exception& e)
3744   {
3745     throw e;
3746   }
3747
3748 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
3749 try
3750   {
3751     loadFromFile(fileName,mName);
3752   }
3753 catch(INTERP_KERNEL::Exception& e)
3754   {
3755     throw e;
3756   }
3757
3758 MEDFileMeshes *MEDFileMeshes::New()
3759 {
3760   return new MEDFileMeshes;
3761 }
3762
3763 MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
3764 {
3765   return new MEDFileMeshes(fileName);
3766 }
3767
3768 void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
3769 {
3770   checkCoherency();
3771   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
3772     {
3773       (*it)->copyOptionsFrom(*this);
3774       (*it)->write(fid);
3775     }
3776 }
3777
3778 void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
3779 {
3780   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
3781   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
3782   std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
3783   MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
3784   checkCoherency();
3785   write(fid);
3786 }
3787
3788 int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
3789 {
3790   return _meshes.size();
3791 }
3792
3793 MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
3794 {
3795   return new MEDFileMeshesIterator(this);
3796 }
3797
3798 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
3799 {
3800   if(i<0 || i>=(int)_meshes.size())
3801     {
3802       std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
3803       throw INTERP_KERNEL::Exception(oss.str().c_str());
3804     }
3805   return _meshes[i]->getOneTimeStep();
3806 }
3807
3808 MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
3809 {
3810   std::vector<std::string> ms=getMeshesNames();
3811   std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
3812   if(it==ms.end())
3813     {
3814       std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh  \"" << mname << "\" does not exist in this ! Existing are : ";
3815       std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
3816       throw INTERP_KERNEL::Exception(oss.str().c_str());
3817     }
3818   return getMeshAtPos((int)std::distance(ms.begin(),it));
3819 }
3820
3821 std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
3822 {
3823   std::vector<std::string> ret(_meshes.size());
3824   int i=0;
3825   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
3826     {
3827       const MEDFileMeshMultiTS *f=(*it);
3828       if(f)
3829         {
3830           ret[i]=f->getName();
3831         }
3832       else
3833         {
3834           std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
3835           throw INTERP_KERNEL::Exception(oss.str().c_str());
3836         }
3837     }
3838   return ret;
3839 }
3840
3841 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
3842 {
3843   bool ret=false;
3844   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
3845     {
3846       MEDFileMeshMultiTS *cur(*it);
3847       if(cur)
3848         ret=cur->changeNames(modifTab) || ret;
3849     }
3850   return ret;
3851 }
3852
3853 void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
3854 {
3855   _meshes.resize(newSize);
3856 }
3857
3858 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
3859 {
3860   if(!mesh)
3861     throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
3862   MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
3863   elt->setOneTimeStep(mesh);
3864   _meshes.push_back(elt);
3865 }
3866
3867 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
3868 {
3869   if(!mesh)
3870     throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
3871   if(i>=(int)_meshes.size())
3872     _meshes.resize(i+1);
3873   MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
3874   elt->setOneTimeStep(mesh);
3875   _meshes[i]=elt;
3876 }
3877
3878 void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
3879 {
3880   if(i<0 || i>=(int)_meshes.size())
3881     {
3882       std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
3883       throw INTERP_KERNEL::Exception(oss.str().c_str());
3884     }
3885   _meshes.erase(_meshes.begin()+i);
3886 }
3887
3888 void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
3889 {
3890   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
3891   int i=0;
3892   _meshes.resize(ms.size());
3893   for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3894     _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str());
3895 }
3896
3897 MEDFileMeshes::MEDFileMeshes()
3898 {
3899 }
3900
3901 MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
3902 try
3903   {
3904     loadFromFile(fileName);
3905   }
3906 catch(INTERP_KERNEL::Exception& e)
3907   {
3908   }
3909
3910 MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
3911 {
3912   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
3913   std::size_t i=0;
3914   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
3915     if((const MEDFileMeshMultiTS *)*it)
3916       meshes[i]=(*it)->deepCpy();
3917   MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
3918   ret->_meshes=meshes;
3919   return ret.retn();
3920 }
3921
3922 std::size_t MEDFileMeshes::getHeapMemorySize() const
3923 {
3924   std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
3925   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
3926     if((const MEDFileMeshMultiTS*)*it)
3927       ret+=(*it)->getHeapMemorySize();
3928   return ret; 
3929 }
3930
3931 std::string MEDFileMeshes::simpleRepr() const
3932 {
3933   std::ostringstream oss;
3934   oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
3935   simpleReprWithoutHeader(oss);
3936   return oss.str();
3937 }
3938
3939 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
3940 {
3941   int nbOfMeshes=getNumberOfMeshes();
3942   oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
3943   std::vector<std::string> mns=getMeshesNames();
3944   for(int i=0;i<nbOfMeshes;i++)
3945     oss << "  - #" << i << " \"" << mns[i] << "\"\n";
3946 }
3947
3948 void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
3949 {
3950   static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
3951   int i=0;
3952   std::set<std::string> s;
3953   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
3954     {
3955       const MEDFileMeshMultiTS *elt=(*it);
3956       if(!elt)
3957         {
3958           std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
3959           throw INTERP_KERNEL::Exception(oss.str().c_str());
3960         }
3961       std::size_t sz=s.size();
3962       s.insert(std::string((*it)->getName()));
3963       if(s.size()==sz)
3964         {
3965           std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
3966           throw INTERP_KERNEL::Exception(oss.str().c_str());
3967         }
3968     }
3969 }
3970
3971 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
3972 {
3973   if(ms)
3974     {
3975       ms->incrRef();
3976       _nb_iter=ms->getNumberOfMeshes();
3977     }
3978 }
3979
3980 MEDFileMeshesIterator::~MEDFileMeshesIterator()
3981 {
3982 }
3983
3984 MEDFileMesh *MEDFileMeshesIterator::nextt()
3985 {
3986   if(_iter_id<_nb_iter)
3987     {
3988       MEDFileMeshes *ms(_ms);
3989       if(ms)
3990         return ms->getMeshAtPos(_iter_id++);
3991       else
3992         return 0;
3993     }
3994   else
3995     return 0;
3996 }