Salome HOME
Merge from V6_main 12/04/2013
[tools/medcoupling.git] / src / MEDLoader / MEDFileMesh.cxx
1 // Copyright (C) 2007-2013  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   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
664   std::vector<std::string> familiesOnWholeGroup;
665   for(const int *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           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1003           std::map<int,int> ren;
1004           for(const int *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(const int *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           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1029           std::map<int,int> ren;
1030           for(const int *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(const int *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           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1053           fam->fillWithZero();
1054           for(const int *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           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1095           std::map<int,int> ren;
1096           for(const int *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(const int *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           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1120           std::map<int,int> ren;
1121           for(const int *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(const int *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   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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 DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1271 {
1272   std::map<int,std::string> famInv;
1273   for(const int *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   if((const DataArrayAsciiChar *)_name_coords)
1443     ret+=_name_coords->getHeapMemorySize();
1444   ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1445   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1446     if((const MEDFileUMeshSplitL1*) *it)
1447       ret+=(*it)->getHeapMemorySize();
1448   return ret;
1449 }
1450
1451 MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
1452 {
1453   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1454   return ret.retn();
1455 }
1456
1457 MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
1458 {
1459   MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1460   if((const DataArrayDouble*)_coords)
1461     ret->_coords=_coords->deepCpy();
1462   if((const DataArrayInt*)_fam_coords)
1463     ret->_fam_coords=_fam_coords->deepCpy();
1464   if((const DataArrayInt*)_num_coords)
1465     ret->_num_coords=_num_coords->deepCpy();
1466   if((const DataArrayInt*)_rev_num_coords)
1467     ret->_rev_num_coords=_rev_num_coords->deepCpy();
1468   if((const DataArrayAsciiChar*)_name_coords)
1469     ret->_name_coords=_name_coords->deepCpy();
1470   std::size_t i=0;
1471   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
1472     {
1473       if((const MEDFileUMeshSplitL1 *)(*it))
1474         ret->_ms[i]=(*it)->deepCpy();
1475     }
1476   return ret.retn();
1477 }
1478
1479 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
1480 {
1481   if(!MEDFileMesh::isEqual(other,eps,what))
1482     return false;
1483   const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
1484   if(!otherC)
1485     {
1486       what="Mesh types differ ! This is unstructured and other is NOT !";
1487       return false;
1488     }
1489   clearNonDiscrAttributes();
1490   otherC->clearNonDiscrAttributes();
1491   const DataArrayDouble *coo1=_coords;
1492   const DataArrayDouble *coo2=otherC->_coords;
1493   if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
1494     {
1495       what="Mismatch of coordinates ! One is defined and not other !";
1496       return false;
1497     }
1498   if(coo1)
1499     {
1500       bool ret=coo1->isEqual(*coo2,eps);
1501       if(!ret)
1502         {
1503           what="Coords differ !";
1504           return false;
1505         }
1506     }
1507   const DataArrayInt *famc1=_fam_coords;
1508   const DataArrayInt *famc2=otherC->_fam_coords;
1509   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
1510     {
1511       what="Mismatch of families arr on nodes ! One is defined and not other !";
1512       return false;
1513     }
1514   if(famc1)
1515     {
1516       bool ret=famc1->isEqual(*famc2);
1517       if(!ret)
1518         {
1519           what="Families arr on node differ !";
1520           return false;
1521         }
1522     }
1523   const DataArrayInt *numc1=_num_coords;
1524   const DataArrayInt *numc2=otherC->_num_coords;
1525   if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
1526     {
1527       what="Mismatch of numbering arr on nodes ! One is defined and not other !";
1528       return false;
1529     }
1530   if(numc1)
1531     {
1532       bool ret=numc1->isEqual(*numc2);
1533       if(!ret)
1534         {
1535           what="Numbering arr on node differ !";
1536           return false;
1537         }
1538     }
1539   const DataArrayAsciiChar *namec1=_name_coords;
1540   const DataArrayAsciiChar *namec2=otherC->_name_coords;
1541   if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
1542     {
1543       what="Mismatch of naming arr on nodes ! One is defined and not other !";
1544       return false;
1545     }
1546   if(namec1)
1547     {
1548       bool ret=namec1->isEqual(*namec2);
1549       if(!ret)
1550         {
1551           what="Names arr on node differ !";
1552           return false;
1553         }
1554     }
1555   if(_ms.size()!=otherC->_ms.size())
1556     {
1557       what="Number of levels differs !";
1558       return false;
1559     }
1560   std::size_t sz=_ms.size();
1561   for(std::size_t i=0;i<sz;i++)
1562     {
1563       const MEDFileUMeshSplitL1 *s1=_ms[i];
1564       const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
1565       if((s1==0 && s2!=0) || (s1!=0 && s2==0))
1566         {
1567           what="Mismatch of presence of sub levels !";
1568           return false;
1569         }
1570       if(s1)
1571         {
1572           bool ret=s1->isEqual(s2,eps,what);
1573           if(!ret)
1574             return false;
1575         }
1576     }
1577   return true;
1578 }
1579
1580 void MEDFileUMesh::clearNonDiscrAttributes() const
1581 {
1582   MEDFileMesh::clearNonDiscrAttributes();
1583   const DataArrayDouble *coo1=_coords;
1584   if(coo1)
1585     (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
1586   const DataArrayInt *famc1=_fam_coords;
1587   if(famc1)
1588     (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
1589   const DataArrayInt *numc1=_num_coords;
1590   if(numc1)
1591     (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
1592   const DataArrayAsciiChar *namc1=_name_coords;
1593   if(namc1)
1594     (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
1595   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1596     {
1597       const MEDFileUMeshSplitL1 *tmp=(*it);
1598       if(tmp)
1599         tmp->clearNonDiscrAttributes();
1600     }
1601 }
1602
1603 MEDFileUMesh::MEDFileUMesh()
1604 {
1605 }
1606
1607 MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
1608 try
1609   {
1610     loadUMeshFromFile(fid,mName,dt,it);
1611   }
1612 catch(INTERP_KERNEL::Exception& e)
1613   {
1614     throw e;
1615   }
1616
1617 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
1618 {
1619   MEDFileUMeshL2 loaderl2;
1620   ParaMEDMEM::MEDCouplingMeshType meshType;
1621   int dummy0,dummy1;
1622   std::string dummy2;
1623   int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
1624   if(meshType!=UNSTRUCTURED)
1625     {
1626       std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
1627       throw INTERP_KERNEL::Exception(oss.str().c_str());
1628     }
1629   loaderl2.loadAll(fid,mid,mName,dt,it);
1630   int lev=loaderl2.getNumberOfLevels();
1631   _ms.resize(lev);
1632   for(int i=0;i<lev;i++)
1633     {
1634       if(!loaderl2.emptyLev(i))
1635         _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
1636       else
1637         _ms[i]=0;
1638     }
1639   MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups);
1640   //
1641   setName(loaderl2.getName());
1642   setDescription(loaderl2.getDescription());
1643   setIteration(loaderl2.getIteration());
1644   setOrder(loaderl2.getOrder());
1645   setTimeValue(loaderl2.getTime());
1646   setTimeUnit(loaderl2.getTimeUnit());
1647   _coords=loaderl2.getCoords();
1648   _fam_coords=loaderl2.getCoordsFamily();
1649   _num_coords=loaderl2.getCoordsNum();
1650   _name_coords=loaderl2.getCoordsName();
1651   computeRevNum();
1652 }
1653
1654 MEDFileUMesh::~MEDFileUMesh()
1655 {
1656 }
1657
1658 void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
1659 {
1660   const DataArrayDouble *coo=_coords;
1661   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1662   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
1663   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
1664   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
1665   int spaceDim=coo?coo->getNumberOfComponents():0;
1666   int mdim=getMeshDimension();
1667   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
1668   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
1669   for(int i=0;i<spaceDim;i++)
1670     {
1671       std::string info=coo->getInfoOnComponent(i);
1672       std::string c,u;
1673       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
1674       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
1675       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
1676     }
1677   MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
1678   MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
1679   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1680     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
1681       (*it)->write(fid,maa,mdim);
1682   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
1683 }
1684
1685 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
1686 {
1687   std::vector<int> ret;
1688   int lev=0;
1689   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
1690     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
1691       if(!(*it)->empty())
1692         ret.push_back(lev);
1693   return ret;
1694 }
1695
1696 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
1697 {
1698   std::vector<int> ret0=getNonEmptyLevels();
1699   if((const DataArrayDouble *) _coords)
1700     {
1701       std::vector<int> ret(ret0.size()+1);
1702       ret[0]=1;
1703       std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
1704       return ret;
1705     }
1706   return ret0;
1707 }
1708
1709 /*!
1710  * This methods returns all relative mesh levels where group 'grp' is defined \b excluded \b nodes.
1711  * To include nodes call MEDFileUMesh::getGrpNonEmptyLevelsExt method.
1712  */
1713 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception)
1714 {
1715   std::vector<std::string> fams=getFamiliesOnGroup(grp);
1716   return getFamsNonEmptyLevels(fams);
1717 }
1718
1719 /*!
1720  * 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.
1721  */
1722 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception)
1723 {
1724   std::vector<std::string> fams=getFamiliesOnGroup(grp);
1725   return getFamsNonEmptyLevelsExt(fams);
1726 }
1727
1728 /*!
1729  * This methods returns all relative mesh levels where family 'fam' is defined \b excluded \b nodes.
1730  * To include nodes call MEDFileUMesh::getFamNonEmptyLevelsExt method.
1731  */
1732 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw(INTERP_KERNEL::Exception)
1733 {
1734   std::vector<std::string> fams(1,std::string(fam));
1735   return getFamsNonEmptyLevels(fams);
1736 }
1737
1738 /*!
1739  * 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.
1740  */
1741 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const throw(INTERP_KERNEL::Exception)
1742 {
1743   std::vector<std::string> fams(1,std::string(fam));
1744   return getFamsNonEmptyLevelsExt(fams);
1745 }
1746
1747 /*!
1748  * This methods returns all relative mesh levels where groups 'grps' are defined \b excluded \b nodes.
1749  * To include nodes call MEDFileUMesh::getGrpsNonEmptyLevelsExt method.
1750  */
1751 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
1752 {
1753   std::vector<std::string> fams=getFamiliesOnGroups(grps);
1754   return getFamsNonEmptyLevels(fams);
1755 }
1756
1757 /*!
1758  * 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.
1759  */
1760 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
1761 {
1762   std::vector<std::string> fams=getFamiliesOnGroups(grps);
1763   return getFamsNonEmptyLevelsExt(fams);
1764 }
1765
1766 /*!
1767  * This methods returns all relative mesh levels where families 'fams' are defined \b excluded \b nodes.
1768  * To include nodes call MEDFileUMesh::getFamsNonEmptyLevelsExt method.
1769  */
1770 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
1771 {
1772   std::vector<int> ret;
1773   std::vector<int> levs=getNonEmptyLevels();
1774   std::vector<int> famIds=getFamiliesIds(fams);
1775   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1776     if(_ms[-(*it)]->presenceOfOneFams(famIds))
1777       ret.push_back(*it);
1778   return ret;
1779 }
1780
1781 /*!
1782  * 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.
1783  */
1784 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
1785 {
1786   std::vector<int> ret0=getFamsNonEmptyLevels(fams);
1787   const DataArrayInt *famCoords=_fam_coords;
1788   if(!famCoords)
1789     return ret0;
1790   std::vector<int> famIds=getFamiliesIds(fams);
1791   if(famCoords->presenceOfValue(famIds))
1792     {
1793       std::vector<int> ret(ret0.size()+1);
1794       ret[0]=1;
1795       std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
1796       return ret;
1797     }
1798   else
1799     return ret0;
1800 }
1801
1802 /*!
1803  * This method retrives all groups that partly or fully appear on the level 'meshDimRelToMaxExt'.
1804  */
1805 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1806 {
1807   std::vector<std::string> ret;
1808   std::vector<std::string> allGrps=getGroupsNames();
1809   for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
1810     {
1811       std::vector<int> levs=getGrpNonEmptyLevelsExt((*it).c_str());
1812       if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
1813         ret.push_back(*it);
1814     }
1815   return ret;
1816 }
1817
1818 int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
1819 {
1820   int ret=-std::numeric_limits<int>::max(),tmp=-1;
1821   if((const DataArrayInt *)_fam_coords)
1822     {
1823       int val=_fam_coords->getMaxValue(tmp);
1824       ret=std::max(ret,val);
1825     }
1826   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1827     {
1828       if((const MEDFileUMeshSplitL1 *)(*it))
1829         {
1830           const DataArrayInt *da=(*it)->getFamilyField();
1831           if(da)
1832             {
1833               int val=_fam_coords->getMaxValue(tmp);
1834               ret=std::max(ret,val);
1835             }
1836         }
1837     }
1838   return ret;
1839 }
1840
1841 int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
1842 {
1843   int ret=std::numeric_limits<int>::max(),tmp=-1;
1844   if((const DataArrayInt *)_fam_coords)
1845     {
1846       int val=_fam_coords->getMinValue(tmp);
1847       ret=std::min(ret,val);
1848     }
1849   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1850     {
1851       if((const MEDFileUMeshSplitL1 *)(*it))
1852         {
1853           const DataArrayInt *da=(*it)->getFamilyField();
1854           if(da)
1855             {
1856               int val=_fam_coords->getMinValue(tmp);
1857               ret=std::min(ret,val);
1858             }
1859         }
1860     }
1861   return ret;
1862 }
1863
1864 int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
1865 {
1866   int lev=0;
1867   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
1868     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
1869       return (*it)->getMeshDimension()+lev;
1870   throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
1871 }
1872
1873 int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
1874 {
1875   const DataArrayDouble *coo=_coords;
1876   if(!coo)
1877     throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
1878   return coo->getNumberOfComponents();
1879 }
1880
1881 std::string MEDFileUMesh::simpleRepr() const
1882 {
1883   std::ostringstream oss;
1884   oss << MEDFileMesh::simpleRepr();
1885   const DataArrayDouble *coo=_coords;
1886   oss << "- The dimension of the space is ";
1887   static const char MSG1[]= "*** NO COORDS SET ***";
1888   static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
1889   if(coo)
1890     oss << _coords->getNumberOfComponents() << std::endl;
1891   else
1892     oss << MSG1 << std::endl;
1893   oss << "- Type of the mesh : UNSTRUCTURED\n";
1894   oss << "- Number of nodes : ";
1895   if(coo)
1896     oss << _coords->getNumberOfTuples() << std::endl;
1897   else
1898     oss << MSG1 << std::endl;
1899   std::size_t nbOfLev=_ms.size();
1900   oss << "- Number of levels allocated : " << nbOfLev << std::endl;
1901   for(std::size_t i=0;i<nbOfLev;i++)
1902     {
1903       const MEDFileUMeshSplitL1 *lev=_ms[i];
1904       oss << "  - Level #" << -((int) i) << " has dimension : ";
1905       if(lev)
1906         {
1907           oss << lev->getMeshDimension() << std::endl;
1908           lev->simpleRepr(oss);
1909         }
1910       else
1911         oss << MSG2 << std::endl;
1912     }
1913   oss << "- Number of families : " << _families.size() << std::endl << std::endl;
1914   if(coo)
1915     {
1916       oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
1917       oss << "- Names of coordinates :" << std::endl;
1918       std::vector<std::string> vars=coo->getVarsOnComponent();
1919       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
1920       oss << std::endl << "- Units of coordinates : " << std::endl;
1921       std::vector<std::string> units=coo->getUnitsOnComponent();
1922       std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
1923     }
1924   oss << std::endl << std::endl;
1925   getFamilyRepr(oss);
1926   return oss.str();
1927 }
1928
1929 std::string MEDFileUMesh::advancedRepr() const
1930 {
1931   return simpleRepr();
1932 }
1933
1934 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1935 {
1936   if(meshDimRelToMaxExt==1)
1937     {
1938       if(!((const DataArrayDouble *)_coords))
1939         throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
1940       return _coords->getNumberOfTuples();
1941     }
1942   return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
1943 }
1944
1945 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1946 {
1947   if(meshDimRelToMaxExt==1)
1948     return _fam_coords;
1949   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
1950   return l1->getFamilyField();
1951 }
1952
1953 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1954 {
1955   if(meshDimRelToMaxExt==1)
1956     return _num_coords;
1957   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
1958   return l1->getNumberField();
1959 }
1960
1961 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1962 {
1963   if(meshDimRelToMaxExt==1)
1964     return _name_coords;
1965   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
1966   return l1->getNameField();
1967 }
1968
1969 int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
1970 {
1971   const DataArrayDouble *coo=_coords;
1972   if(!coo)
1973     throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
1974   return coo->getNumberOfTuples();
1975 }
1976
1977 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
1978 {
1979   if(meshDimRelToMaxExt==1)
1980     {
1981       if(!((const DataArrayInt *)_num_coords))
1982         throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
1983       return _rev_num_coords;
1984     }
1985   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
1986   return l1->getRevNumberField();
1987 }
1988
1989 /*!
1990  * This method returns coordinates in 'this'. The returned array reference counter is \b not incremented by this method (as MEDCouplingPointSet::getCoords does).
1991  */
1992 DataArrayDouble *MEDFileUMesh::getCoords() const
1993 {
1994   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
1995   if((DataArrayDouble *)tmp)
1996     {
1997       return tmp;
1998     }
1999   return 0;
2000 }
2001
2002 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
2003 {
2004   synchronizeTinyInfoOnLeaves();
2005   std::vector<std::string> tmp(1);
2006   tmp[0]=grp;
2007   MEDCouplingUMesh *ret=getGroups(meshDimRelToMaxExt,tmp,renum);
2008   ret->setName(grp);
2009   return ret;
2010 }
2011
2012 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
2013 {
2014   synchronizeTinyInfoOnLeaves();
2015   std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2016   return getFamilies(meshDimRelToMaxExt,fams2,renum);
2017 }
2018
2019 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
2020 {
2021   synchronizeTinyInfoOnLeaves();
2022   std::vector<std::string> tmp(1);
2023   tmp[0]=fam;
2024   MEDCouplingUMesh *ret=getFamilies(meshDimRelToMaxExt,tmp,renum);
2025   ret->setName(fam);
2026   return ret;
2027 }
2028
2029 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2030 {
2031   synchronizeTinyInfoOnLeaves();
2032   if(meshDimRelToMaxExt==1)
2033     {
2034       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2035       MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2036       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2037       ret->setCoords(c);
2038       return ret.retn();
2039     }
2040   std::vector<int> famIds=getFamiliesIds(fams);
2041   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2042   if(!famIds.empty())
2043     return l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2044   else
2045     return l1->getFamilyPart(0,0,renum);
2046 }
2047
2048 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2049 {
2050   std::vector<int> famIds=getFamiliesIds(fams);
2051   if(meshDimRelToMaxExt==1)
2052     {
2053       if((const DataArrayInt *)_fam_coords)
2054         {
2055           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2056           if(!famIds.empty())
2057             da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2058           else
2059             da=_fam_coords->getIdsEqualList(0,0);
2060           if(renum)
2061             return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2062           else
2063             return da.retn();
2064         }
2065       else
2066         throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2067     }
2068   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2069   if(!famIds.empty())
2070     return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2071   else
2072     return l1->getFamilyPartArr(0,0,renum);
2073 }
2074
2075 /*!
2076  * Returns a pointer to mesh at the specified level. ** WARNING **, if the input \a meshDimRelToMaxExt is set to one (nodes),
2077  * The returned mesh ** will be not valid **. It is a feature, because MEDLoader do not creates cells that do not exist !
2078  * To build a valid MEDCouplingUMesh instance from the returned value when \a meshDimRelToMaxExt is equal to one, simply
2079  * call MEDCouplingUMesh::Build0DMeshFromCoords.
2080  * 
2081  * \return a pointer to unstructured mesh that need to be managed by the caller.
2082  * \warning the returned pointer has to be managed by the caller.
2083  * \sa MEDFileUMesh::getGenMeshAtLevel
2084  */
2085 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
2086 {
2087   synchronizeTinyInfoOnLeaves();
2088   if(meshDimRelToMaxExt==1)
2089     {
2090       if(!renum)
2091         {
2092           MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2093           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2094           umesh->setCoords(cc);
2095           MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2096           umesh->setName(getName());
2097           return umesh;
2098         }
2099     }
2100   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2101   return l1->getWholeMesh(renum);
2102 }
2103
2104 /*!
2105  * Returns a pointer to mesh at the specified level.
2106  * 
2107  * \return a pointer to unstructured mesh that need to be managed by the caller.
2108  * \warning the returned pointer has to be managed by the caller.
2109  * \sa MEDFileUMesh::getMeshAtLevel
2110  */
2111 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
2112 {
2113   return getMeshAtLevel(meshDimRelToMax,renum);
2114 }
2115
2116 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2117 {
2118   return getMeshAtLevel(0,renum);
2119 }
2120
2121 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2122 {
2123   return getMeshAtLevel(-1,renum);
2124 }
2125
2126 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2127 {
2128   return getMeshAtLevel(-2,renum);
2129 }
2130
2131 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2132 {
2133   return getMeshAtLevel(-3,renum);
2134 }
2135
2136 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2137 {
2138   if(meshDimRelToMaxExt==1)
2139     throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2140   if(meshDimRelToMaxExt>1)
2141     throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2142   int tracucedRk=-meshDimRelToMaxExt;
2143   if(tracucedRk>=(int)_ms.size())
2144     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2145   if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2146     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2147   return _ms[tracucedRk];
2148 }
2149
2150 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2151 {
2152    if(meshDimRelToMaxExt==1)
2153     throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2154   if(meshDimRelToMaxExt>1)
2155     throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2156   int tracucedRk=-meshDimRelToMaxExt;
2157   if(tracucedRk>=(int)_ms.size())
2158     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2159   if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2160     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2161   return _ms[tracucedRk];
2162 }
2163
2164 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2165 {
2166   if(-meshDimRelToMax>=(int)_ms.size())
2167     throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
2168   int i=0;
2169   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2170     {
2171       if(((const MEDFileUMeshSplitL1*) (*it))!=0)
2172         {
2173           int ref=(*it)->getMeshDimension();
2174           if(ref+i!=meshDim-meshDimRelToMax)
2175             throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
2176         }
2177     }
2178 }
2179
2180 void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
2181 {
2182   if(!coords)
2183     throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
2184   coords->checkAllocated();
2185   int nbOfTuples=coords->getNumberOfTuples();
2186   _coords=coords;
2187   coords->incrRef();
2188   _fam_coords=DataArrayInt::New();
2189   _fam_coords->alloc(nbOfTuples,1);
2190   _fam_coords->fillWithZero();
2191 }
2192
2193 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2194 {
2195   if(meshDimRelToMaxExt==1)
2196     {
2197       if((DataArrayInt *)_fam_coords)
2198         _fam_coords->fillWithZero();
2199       return ;
2200     }
2201   MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2202   l1->eraseFamilyField();
2203   optimizeFamilies();
2204 }
2205
2206 void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
2207 {
2208   std::vector<int> levs=getNonEmptyLevelsExt();
2209   std::set<int> allFamsIds;
2210   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2211     {
2212       const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
2213       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
2214       std::set<int> res;
2215       std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
2216       allFamsIds=res;
2217     }
2218   std::set<std::string> famNamesToKill;
2219   for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2220     {
2221       if(allFamsIds.find((*it).second)!=allFamsIds.end())
2222         famNamesToKill.insert((*it).first);
2223     }
2224   for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
2225     _families.erase(*it);
2226   std::vector<std::string> grpNamesToKill;
2227   for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
2228     {
2229       std::vector<std::string> tmp;
2230       for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
2231         {
2232           if(famNamesToKill.find(*it2)==famNamesToKill.end())
2233             tmp.push_back(*it2);
2234         }
2235       if(!tmp.empty())
2236         (*it).second=tmp;
2237       else
2238         tmp.push_back((*it).first);
2239     }
2240   for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
2241     _groups.erase(*it);
2242 }
2243
2244 void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
2245 {
2246   std::vector<int> levs=getNonEmptyLevels();
2247   if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
2248     throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
2249   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
2250   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
2251   int nbNodes=m0->getNumberOfNodes();
2252   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
2253   DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
2254   m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
2255   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
2256   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
2257   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
2258   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
2259   // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
2260   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
2261   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
2262   descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
2263   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
2264   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
2265   DataArrayInt *cellsInM1ToRenumW4Tmp=0;
2266   m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
2267   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
2268   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
2269   cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
2270   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
2271   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
2272   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
2273   m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
2274   m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
2275   // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
2276   tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
2277   m0->setCoords(tmp0->getCoords());
2278   m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
2279   m1->setCoords(m0->getCoords());
2280   _coords=m0->getCoords(); _coords->incrRef();
2281   // duplication of cells in group 'grpNameM1' on level -1
2282   m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
2283   std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
2284   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
2285   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
2286   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
2287   //
2288   newm1->setName(getName());
2289   const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
2290   if(!fam)
2291     throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
2292   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
2293   newFam->alloc(newm1->getNumberOfCells(),1);
2294   int idd=getMaxFamilyId()+1;
2295   int globStart=0,start=0,end,globEnd;
2296   int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
2297   for(int i=0;i<nbOfChunks;i++)
2298     {
2299       globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
2300       if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
2301         {
2302           end=start+szOfCellGrpOfSameType->getIJ(i,0);
2303           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
2304           newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
2305           start=end;
2306         }
2307       else
2308         {
2309           newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
2310         }
2311       globStart=globEnd;
2312     }
2313   newm1->setCoords(getCoords());
2314   setMeshAtLevel(-1,newm1);
2315   setFamilyFieldArr(-1,newFam);
2316   std::string grpName2(grpNameM1); grpName2+="_dup";
2317   addFamily(grpName2.c_str(),idd);
2318   addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
2319   //
2320   fam=_fam_coords;
2321   if(fam)
2322     {
2323       int newNbOfNodes=getCoords()->getNumberOfTuples();
2324       newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
2325       newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
2326       newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
2327       _fam_coords=newFam;
2328     }
2329   nodesDuplicated=nodeIdsToDuplicate.retn();
2330   cellsModified=cellsToModifyConn0.retn();
2331   cellsNotModified=cellsToModifyConn1.retn();
2332 }
2333
2334 /*!
2335  * \param [out] oldCode retrieves the distribution of types before the call if true is returned
2336  * \param [out] newCode etrieves the distribution of types after the call if true is returned
2337  * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
2338  * 
2339  * \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.
2340  * 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.
2341  */
2342 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
2343 {
2344   o2nRenumCell=0; oldCode.clear(); newCode.clear();
2345   std::vector<int> levs=getNonEmptyLevels();
2346   bool ret=false;
2347   std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
2348   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
2349   int start=0;
2350   int end=0;
2351   for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
2352     {
2353       MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
2354       std::vector<int> code1=m->getDistributionOfTypes();
2355       end=PutInThirdComponentOfCodeOffset(code1,start);
2356       oldCode.insert(oldCode.end(),code1.begin(),code1.end());
2357       bool hasChanged=m->unPolyze();
2358       DataArrayInt *fake=0;
2359       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
2360                                                                                            MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
2361       fake->decrRef();
2362       renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
2363       if(hasChanged)
2364         {
2365           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
2366           m->renumberCells(o2nCellsPart2->getConstPointer(),false);
2367           ret=true;
2368           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
2369           const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
2370           const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
2371           setMeshAtLevel(*it,m);
2372           std::vector<int> code2=m->getDistributionOfTypes();
2373           end=PutInThirdComponentOfCodeOffset(code2,start);
2374           newCode.insert(newCode.end(),code2.begin(),code2.end());
2375           //
2376           if(o2nCellsPart2->isIdentity())
2377             continue;
2378           if(famField)
2379             {
2380               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
2381               setFamilyFieldArr(*it,newFamField);
2382             }
2383           if(numField)
2384             {
2385               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
2386               setRenumFieldArr(*it,newNumField);
2387             }
2388         }
2389       else
2390         {
2391           newCode.insert(newCode.end(),code1.begin(),code1.end());
2392         }
2393       start=end;
2394     }
2395   if(ret)
2396     {
2397       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
2398       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
2399       o2nRenumCell=o2nRenumCellRet.retn();
2400     }
2401   return ret;
2402 }
2403
2404 struct MEDLoaderAccVisit1
2405 {
2406   MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
2407   int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
2408   int _new_nb_of_nodes;
2409 };
2410
2411 /*!
2412  * 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.
2413  * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
2414  * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
2415  * -1 values in returned array means that the corresponding old node is no more used.
2416  *
2417  * \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
2418  *         is modified in \a this.
2419  * \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
2420  *  set coordinates.
2421  */
2422 DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
2423 {
2424   const DataArrayDouble *coo=getCoords();
2425   if(!coo)
2426     throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
2427   int nbOfNodes=coo->getNumberOfTuples();
2428   std::vector<bool> nodeIdsInUse(nbOfNodes,false);
2429   std::vector<int> neLevs=getNonEmptyLevels();
2430   for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
2431     {
2432       MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
2433       m->computeNodeIdsAlg(nodeIdsInUse);
2434     }
2435   int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
2436   if(nbrOfNodesInUse==nbOfNodes)
2437     return 0;
2438   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
2439   std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
2440   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
2441   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
2442   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
2443   MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
2444   if((const DataArrayInt *)_fam_coords)
2445     newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
2446   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
2447   if((const DataArrayInt *)_num_coords)
2448     newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
2449   if((const DataArrayAsciiChar *)_name_coords)
2450     newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
2451   _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
2452   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2453     {
2454       if((MEDFileUMeshSplitL1*)*it)
2455         (*it)->renumberNodesInConn(ret->begin());
2456     }
2457   return ret.retn();
2458 }
2459
2460 /*!
2461  * This method is here only to add a group on node.
2462  * MEDFileUMesh::setGroupsAtLevel with 1 in the first parameter.
2463  *
2464  * \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).
2465  */
2466 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
2467 {
2468   const DataArrayDouble *coords=_coords;
2469   if(!coords)
2470     throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
2471   int nbOfNodes=coords->getNumberOfTuples();
2472   if(!((DataArrayInt *)_fam_coords))
2473     { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
2474   //
2475   addGroupUnderground(ids,_fam_coords);
2476 }
2477
2478 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
2479 {
2480   std::vector<int> levs=getNonEmptyLevelsExt();
2481   if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
2482     { 
2483       std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
2484       std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
2485     }
2486   if(meshDimRelToMaxExt==1)
2487     { addNodeGroup(ids); return ; }
2488   MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
2489   DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
2490   addGroupUnderground(ids,fam);
2491 }
2492
2493 /*!
2494  * \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).
2495  * \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)
2496  */
2497 void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
2498 {
2499   if(!ids)
2500     throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
2501   std::string grpName(ids->getName());
2502   if(grpName.empty())
2503     throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
2504   ids->checkStrictlyMonotonic(true);
2505   famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
2506   std::vector<std::string> grpsNames=getGroupsNames();
2507   if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
2508     {
2509       std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
2510       throw INTERP_KERNEL::Exception(oss.str().c_str());
2511     }
2512   std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
2513   allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
2514   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
2515   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
2516   std::vector<int> familyIds;
2517   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
2518   int maxVal=getTheMaxFamilyId()+1;
2519   std::map<std::string,int> families(_families);
2520   std::map<std::string, std::vector<std::string> > groups(_groups);
2521   std::vector<std::string> fams;
2522   bool created(false);
2523   for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
2524     {
2525       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
2526       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
2527       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
2528       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
2529       if(ret0->empty())
2530         {
2531           bool isFamPresent=false;
2532           for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
2533             isFamPresent=(*itl)->presenceOfValue(*famId);
2534           if(!isFamPresent)
2535             { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
2536           else
2537             {
2538               familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ids2); std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,maxVal,created);
2539               fams.push_back(locFamName);
2540               if(existsFamily(*famId))
2541                 {
2542                   std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
2543                   ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
2544                 }
2545               maxVal++;
2546             } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
2547         }
2548       else
2549         {
2550           familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
2551           familyIds.push_back(maxVal+1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
2552           std::string n2(FindOrCreateAndGiveFamilyWithId(families,maxVal+1,created)); fams.push_back(n2);
2553           if(existsFamily(*famId))
2554             {
2555               std::string n1(FindOrCreateAndGiveFamilyWithId(families,maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
2556               ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
2557             }
2558           maxVal+=2;
2559         }
2560     }
2561   for(std::size_t i=0;i<familyIds.size();i++)
2562     {
2563       DataArrayInt *da=idsPerfamiliyIds[i];
2564       famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
2565     }
2566   _families=families;
2567   _groups=groups;
2568   _groups[grpName]=fams;
2569 }
2570
2571 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
2572 {
2573   std::string oldName=getFamilyNameGivenId(id);
2574   _families.erase(oldName);
2575   _families[newFamName]=id;
2576 }
2577
2578 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
2579 {
2580   std::vector<int> levSet=getNonEmptyLevels();
2581   std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
2582   if(it==levSet.end())
2583     throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
2584   int pos=(-meshDimRelToMax);
2585   _ms[pos]=0;
2586 }
2587
2588 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
2589 {
2590   setMeshAtLevelGen(meshDimRelToMax,m,newOrOld);
2591 }
2592
2593 void MEDFileUMesh::setMeshAtLevelGen(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
2594 {
2595   dealWithTinyInfo(m);
2596   std::vector<int> levSet=getNonEmptyLevels();
2597   if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
2598     {
2599       if((DataArrayDouble *)_coords==0)
2600         {
2601           DataArrayDouble *c=m->getCoords();
2602           if(c)
2603             c->incrRef();
2604           _coords=c;
2605         }
2606       if(m->getCoords()!=_coords)
2607         throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
2608       int sz=(-meshDimRelToMax)+1;
2609       if(sz>=(int)_ms.size())
2610         _ms.resize(sz);
2611       checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
2612       _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
2613     }
2614   else
2615     _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
2616 }
2617
2618 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms) throw(INTERP_KERNEL::Exception)
2619 {
2620   if(ms.empty())
2621     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
2622   int sz=(-meshDimRelToMax)+1;
2623   if(sz>=(int)_ms.size())
2624     _ms.resize(sz);
2625   checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
2626   DataArrayDouble *coo=checkMultiMesh(ms);
2627   if((DataArrayDouble *)_coords==0)
2628     {
2629       coo->incrRef();
2630       _coords=coo;
2631     }
2632   else
2633     if((DataArrayDouble *)_coords!=coo)
2634       throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
2635   std::vector<DataArrayInt *> corr;
2636   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
2637   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
2638   setMeshAtLevel(meshDimRelToMax,m);
2639   std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
2640   setGroupsAtLevel(meshDimRelToMax,corr2,true);
2641 }
2642
2643 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
2644 {
2645   if(ms.empty())
2646     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
2647   int sz=(-meshDimRelToMax)+1;
2648   if(sz>=(int)_ms.size())
2649     _ms.resize(sz);
2650   checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
2651   DataArrayDouble *coo=checkMultiMesh(ms);
2652   if((DataArrayDouble *)_coords==0)
2653     {
2654       coo->incrRef();
2655       _coords=coo;
2656     }
2657   else
2658     if((DataArrayDouble *)_coords!=coo)
2659       throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
2660   MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
2661   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
2662   int i=0;
2663   for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
2664     {
2665       DataArrayInt *arr=0;
2666       bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
2667       corr[i]=arr;
2668       if(!test)
2669         {
2670           std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
2671           throw INTERP_KERNEL::Exception(oss.str().c_str());
2672         }
2673     }
2674   std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
2675   setGroupsAtLevel(meshDimRelToMax,corr2,renum);
2676 }
2677
2678 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
2679 {
2680   const DataArrayDouble *ret=ms[0]->getCoords();
2681   int mdim=ms[0]->getMeshDimension();
2682   for(unsigned int i=1;i<ms.size();i++)
2683     {
2684       ms[i]->checkCoherency();
2685       if(ms[i]->getCoords()!=ret)
2686         throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
2687       if(ms[i]->getMeshDimension()!=mdim)
2688         throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
2689     }
2690   return const_cast<DataArrayDouble *>(ret);
2691 }
2692
2693 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
2694 {
2695   if(meshDimRelToMaxExt==1)
2696     {
2697       if(!famArr)
2698         {
2699           _fam_coords=0;
2700           return ;
2701         }
2702       DataArrayDouble *coo(_coords);
2703       if(!coo)
2704         throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
2705       famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
2706       famArr->incrRef();
2707       _fam_coords=famArr;
2708       return ;
2709     }
2710   if(meshDimRelToMaxExt>1)
2711     throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
2712   int traducedRk=-meshDimRelToMaxExt;
2713   if(traducedRk>=(int)_ms.size())
2714     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2715   if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
2716     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2717   return _ms[traducedRk]->setFamilyArr(famArr);
2718 }
2719
2720 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
2721 {
2722   if(meshDimRelToMaxExt==1)
2723     {
2724       if(!renumArr)
2725         {
2726           _num_coords=0;
2727           _rev_num_coords=0;
2728           return ;
2729         }
2730       DataArrayDouble *coo(_coords);
2731       if(!coo)
2732         throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
2733       renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
2734       renumArr->incrRef();
2735       _num_coords=renumArr;
2736       computeRevNum();
2737       return ;
2738     }
2739   if(meshDimRelToMaxExt>1)
2740     throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
2741   int traducedRk=-meshDimRelToMaxExt;
2742   if(traducedRk>=(int)_ms.size())
2743     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2744   if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
2745     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2746   return _ms[traducedRk]->setRenumArr(renumArr);
2747 }
2748
2749 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
2750 {
2751   if(meshDimRelToMaxExt==1)
2752     {
2753       if(!nameArr)
2754         {
2755           _name_coords=0;
2756           return ;
2757         }
2758       DataArrayDouble *coo(_coords);
2759       if(!coo)
2760         throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
2761       nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
2762       nameArr->incrRef();
2763       _name_coords=nameArr;
2764       return ;
2765     }
2766   if(meshDimRelToMaxExt>1)
2767     throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
2768   int traducedRk=-meshDimRelToMaxExt;
2769   if(traducedRk>=(int)_ms.size())
2770     throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2771   if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
2772     throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2773   return _ms[traducedRk]->setNameArr(nameArr);
2774 }
2775
2776 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
2777 {
2778   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2779     if((const MEDFileUMeshSplitL1 *)(*it))
2780       (*it)->synchronizeTinyInfo(*this);
2781 }
2782
2783 /*!
2784  * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
2785  */
2786 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
2787 {
2788   DataArrayInt *arr=_fam_coords;
2789   if(arr)
2790     arr->changeValue(oldId,newId);
2791   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2792     {
2793       MEDFileUMeshSplitL1 *sp=(*it);
2794       if(sp)
2795         {
2796           sp->changeFamilyIdArr(oldId,newId);
2797         }
2798     }
2799 }
2800
2801 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
2802 {
2803   std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
2804   const DataArrayInt *da(_fam_coords);
2805   if(da)
2806     { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
2807   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2808     {
2809       const MEDFileUMeshSplitL1 *elt(*it);
2810       if(elt)
2811         {
2812           da=elt->getFamilyField();
2813           if(da)
2814             { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
2815         }
2816     }
2817   return ret;
2818 }
2819
2820 void MEDFileUMesh::computeRevNum() const
2821 {
2822   if((const DataArrayInt *)_num_coords)
2823     {
2824       int pos;
2825       int maxValue=_num_coords->getMaxValue(pos);
2826       _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
2827     }
2828 }
2829
2830 std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
2831 {
2832   std::size_t ret=MEDFileMesh::getHeapMemorySize();
2833   if((const DataArrayInt*)_fam_nodes)
2834     ret+=_fam_nodes->getHeapMemorySize();
2835   if((const DataArrayInt*)_num_nodes)
2836     ret+=_num_nodes->getHeapMemorySize();
2837   if((const DataArrayInt*)_fam_cells)
2838     ret+=_fam_cells->getHeapMemorySize();
2839   if((const DataArrayInt*)_num_cells)
2840     ret+=_num_cells->getHeapMemorySize();
2841   if((const DataArrayInt*)_rev_num_nodes)
2842     ret+=_rev_num_nodes->getHeapMemorySize();
2843   if((const DataArrayInt*)_rev_num_cells)
2844     ret+=_rev_num_cells->getHeapMemorySize();
2845   return ret;
2846 }
2847
2848 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2849 {
2850   int ret=-std::numeric_limits<int>::max(),tmp=-1;
2851   if((const DataArrayInt *)_fam_nodes)
2852     {
2853       int val=_fam_nodes->getMaxValue(tmp);
2854       ret=std::max(ret,val);
2855     }
2856   if((const DataArrayInt *)_fam_cells)
2857     {
2858       int val=_fam_cells->getMaxValue(tmp);
2859       ret=std::max(ret,val);
2860     }
2861   return ret;
2862 }
2863
2864 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2865 {
2866   int ret=std::numeric_limits<int>::max(),tmp=-1;
2867   if((const DataArrayInt *)_fam_nodes)
2868     {
2869       int val=_fam_nodes->getMinValue(tmp);
2870       ret=std::min(ret,val);
2871     }
2872   if((const DataArrayInt *)_fam_cells)
2873     {
2874       int val=_fam_cells->getMinValue(tmp);
2875       ret=std::min(ret,val);
2876     }
2877   return ret;
2878 }
2879
2880 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2881 {
2882   if(!MEDFileMesh::isEqual(other,eps,what))
2883     return false;
2884   const MEDFileStructuredMesh *otherC=dynamic_cast<const  MEDFileStructuredMesh *>(other);
2885   if(!otherC)
2886     {
2887       what="Mesh types differ ! This is structured and other is NOT !";
2888       return false;
2889     }
2890   const DataArrayInt *famc1=_fam_nodes;
2891   const DataArrayInt *famc2=otherC->_fam_nodes;
2892   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2893     {
2894       what="Mismatch of families arr on nodes ! One is defined and not other !";
2895       return false;
2896     }
2897   if(famc1)
2898     {
2899       bool ret=famc1->isEqual(*famc2);
2900       if(!ret)
2901         {
2902           what="Families arr on nodes differ !";
2903           return false;
2904         }
2905     }
2906   famc1=_fam_cells;
2907   famc2=otherC->_fam_cells;
2908   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2909     {
2910       what="Mismatch of families arr on cells ! One is defined and not other !";
2911       return false;
2912     }
2913   if(famc1)
2914     {
2915       bool ret=famc1->isEqual(*famc2);
2916       if(!ret)
2917         {
2918           what="Families arr on cells differ !";
2919           return false;
2920         }
2921     }
2922   famc1=_num_nodes;
2923   famc2=otherC->_num_nodes;
2924   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2925     {
2926       what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2927       return false;
2928     }
2929   if(famc1)
2930     {
2931       bool ret=famc1->isEqual(*famc2);
2932       if(!ret)
2933         {
2934           what="Numbering arr on nodes differ !";
2935           return false;
2936         }
2937     }
2938   famc1=_num_cells;
2939   famc2=otherC->_num_cells;
2940   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2941     {
2942       what="Mismatch of numbering arr on cells ! One is defined and not other !";
2943       return false;
2944     }
2945   if(famc1)
2946     {
2947       bool ret=famc1->isEqual(*famc2);
2948       if(!ret)
2949         {
2950           what="Numbering arr on cells differ !";
2951           return false;
2952         }
2953     }
2954   const DataArrayAsciiChar *d1=_names_cells;
2955   const DataArrayAsciiChar *d2=otherC->_names_cells;
2956   if((d1==0 && d2!=0) || (d1!=0 && d2==0))
2957     {
2958       what="Mismatch of naming arr on cells ! One is defined and not other !";
2959       return false;
2960     }
2961   if(d1)
2962     {
2963       bool ret=d1->isEqual(*d2);
2964       if(!ret)
2965         {
2966           what="Naming arr on cells differ !";
2967           return false;
2968         }
2969     }
2970   d1=_names_nodes;
2971   d2=otherC->_names_nodes;
2972   if((d1==0 && d2!=0) || (d1!=0 && d2==0))
2973     {
2974       what="Mismatch of naming arr on nodes ! One is defined and not other !";
2975       return false;
2976     }
2977   if(d1)
2978     {
2979       bool ret=d1->isEqual(*d2);
2980       if(!ret)
2981         {
2982           what="Naming arr on nodes differ !";
2983           return false;
2984         }
2985     }
2986   return true;
2987 }
2988
2989 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
2990 {
2991   MEDFileMesh::clearNonDiscrAttributes();
2992   const DataArrayInt *tmp=_fam_nodes;
2993   if(tmp)
2994     (const_cast<DataArrayInt *>(tmp))->setName("");
2995   tmp=_num_nodes;
2996   if(tmp)
2997     (const_cast<DataArrayInt *>(tmp))->setName("");
2998   tmp=_fam_cells;
2999   if(tmp)
3000     (const_cast<DataArrayInt *>(tmp))->setName("");
3001   tmp=_num_cells;
3002   if(tmp)
3003     (const_cast<DataArrayInt *>(tmp))->setName("");
3004 }
3005
3006 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
3007 {
3008   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3009     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
3010   std::vector<int> famIds=getFamiliesIds(fams);
3011   if(meshDimRelToMaxExt==1)
3012     {
3013       if((const DataArrayInt *)_fam_nodes)
3014         {
3015           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3016           if(!famIds.empty())
3017             da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3018           else
3019             da=_fam_nodes->getIdsEqualList(0,0);
3020           if(renum)
3021             return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
3022           else
3023             return da.retn();
3024         }
3025       else
3026         throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
3027     }
3028   else
3029     {
3030       if((const DataArrayInt *)_fam_cells)
3031         {
3032           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3033           if(!famIds.empty())
3034             da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3035           else
3036             da=_fam_cells->getIdsEqualList(0,0);
3037           if(renum)
3038             return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
3039           else
3040             return da.retn();
3041         }
3042       else
3043         throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
3044     }
3045 }
3046
3047 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3048 {
3049   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3050     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
3051   const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
3052   if(!mesh)
3053     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
3054   if(meshDimRelToMaxExt==0)
3055     {
3056       int nbCells=mesh->getNumberOfCells();
3057       famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
3058       _fam_cells=famArr;
3059     }
3060   else
3061     {
3062       int nbNodes=mesh->getNumberOfNodes();
3063       famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
3064       _fam_nodes=famArr;
3065     }
3066   if(famArr)
3067     famArr->incrRef();
3068 }
3069
3070 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
3071 {
3072   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3073     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
3074   const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
3075   if(!mesh)
3076     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
3077   if(meshDimRelToMaxExt==0)
3078     {
3079       int nbCells=mesh->getNumberOfCells();
3080       renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
3081       _num_cells=renumArr;
3082     }
3083   else
3084     {
3085       int nbNodes=mesh->getNumberOfNodes();
3086       renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
3087       _num_nodes=renumArr;
3088     }
3089   if(renumArr)
3090     renumArr->incrRef();
3091 }
3092
3093 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
3094 {
3095   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3096     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
3097   const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
3098   if(!mesh)
3099     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
3100   if(meshDimRelToMaxExt==0)
3101     {
3102       int nbCells=mesh->getNumberOfCells();
3103       nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
3104       _names_cells=nameArr;
3105     }
3106   else
3107     {
3108       int nbNodes=mesh->getNumberOfNodes();
3109       nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
3110       _names_nodes=nameArr;
3111     }
3112   if(nameArr)
3113     nameArr->incrRef();
3114 }
3115
3116 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3117 {
3118   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3119     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
3120   if(meshDimRelToMaxExt==0)
3121     return _fam_cells;
3122   else
3123     return _fam_nodes;
3124 }
3125
3126 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3127 {
3128   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3129     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
3130   if(meshDimRelToMaxExt==0)
3131     return _num_cells;
3132   else
3133     return _num_nodes;
3134 }
3135
3136 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3137 {
3138   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3139     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
3140   if(meshDimRelToMaxExt==0)
3141     {
3142       if((const DataArrayInt *)_num_cells)
3143         {
3144           int pos;
3145           int maxValue=_num_cells->getMaxValue(pos);
3146           _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
3147           return _rev_num_cells;
3148         }
3149       else
3150         throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
3151     }
3152   else
3153     {
3154       if((const DataArrayInt *)_num_nodes)
3155         {
3156           int pos;
3157           int maxValue=_num_nodes->getMaxValue(pos);
3158           _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
3159           return _rev_num_nodes;
3160         }
3161       else
3162         throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
3163     }
3164 }
3165
3166 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3167 {
3168   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3169     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
3170   if(meshDimRelToMaxExt==0)
3171     return _names_cells;
3172   else
3173     return _names_nodes;
3174 }
3175
3176 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
3177 {
3178   std::vector<int> ret(1);
3179   return ret;
3180 }
3181
3182 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
3183 {
3184   std::vector<int> ret(2);
3185   ret[0]=1;
3186   return ret;
3187 }
3188
3189 /*!
3190  * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
3191  */
3192 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
3193 {
3194   oldCode.clear(); newCode.clear(); o2nRenumCell=0;
3195   return false;
3196 }
3197
3198 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3199 {
3200   DataArrayInt *arr=_fam_nodes;
3201   if(arr)
3202     arr->changeValue(oldId,newId);
3203   arr=_fam_cells;
3204   if(arr)
3205     arr->changeValue(oldId,newId);
3206 }
3207
3208 void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
3209 {
3210   if((const DataArrayInt*)_fam_nodes)
3211     _fam_nodes=_fam_nodes->deepCpy();
3212   if((const DataArrayInt*)_num_nodes)
3213     _num_nodes=_num_nodes->deepCpy();
3214   if((const DataArrayInt*)_fam_cells)
3215     _fam_cells=_fam_cells->deepCpy();
3216   if((const DataArrayInt*)_num_cells)
3217     _num_cells=_num_cells->deepCpy();
3218   if((const DataArrayInt*)_rev_num_nodes)
3219     _rev_num_nodes=_rev_num_nodes->deepCpy();
3220   if((const DataArrayInt*)_rev_num_cells)
3221     _rev_num_cells=_rev_num_cells->deepCpy();
3222 }
3223
3224 /*!
3225  * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
3226  * 
3227  * \return a pointer to cartesian mesh that need to be managed by the caller.
3228  * \warning the returned pointer has to be managed by the caller.
3229  */
3230 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
3231 {
3232   if(renum)
3233     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
3234   if(meshDimRelToMax!=0)
3235     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
3236   const MEDCouplingStructuredMesh *m=getStructuredMesh();
3237   if(m)
3238     m->incrRef();
3239   return const_cast<MEDCouplingStructuredMesh *>(m);
3240 }
3241
3242 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3243 {
3244   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3245     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
3246   const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
3247   if(!cmesh)
3248     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
3249   if(meshDimRelToMaxExt==0)
3250     return cmesh->getNumberOfCells();
3251   else
3252     return cmesh->getNumberOfNodes();
3253 }
3254
3255 int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
3256 {
3257   const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
3258   if(!cmesh)
3259     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
3260   return cmesh->getNumberOfNodes();
3261 }
3262
3263 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
3264 {
3265   med_geometry_type geoTypeReq=MED_NONE;
3266   switch(meshDim)
3267     {
3268     case 3:
3269       geoTypeReq=MED_HEXA8;
3270       break;
3271     case 2:
3272       geoTypeReq=MED_QUAD4;
3273       break;
3274     case 1:
3275       geoTypeReq=MED_SEG2;
3276       break;
3277     case 0:
3278       geoTypeReq=MED_POINT1;
3279       break;
3280     default:
3281       throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
3282     }
3283   return geoTypeReq;
3284 }
3285
3286 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3287 {
3288   setName(strm->getName());
3289   setDescription(strm->getDescription());
3290   setIteration(strm->getIteration());
3291   setOrder(strm->getOrder());
3292   setTimeValue(strm->getTime());
3293   setTimeUnit(strm->getTimeUnit());
3294   MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups);
3295   med_bool chgt=MED_FALSE,trsf=MED_FALSE;
3296   int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
3297   if(nbOfElt>0)
3298     {
3299       _fam_nodes=DataArrayInt::New();
3300       _fam_nodes->alloc(nbOfElt,1);
3301       MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
3302     }
3303   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
3304   if(nbOfElt>0)
3305     {
3306       _num_nodes=DataArrayInt::New();
3307       _num_nodes->alloc(nbOfElt,1);
3308       MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
3309     }
3310   int meshDim=getStructuredMesh()->getMeshDimension();
3311   med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
3312   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
3313   if(nbOfElt>0)
3314     {
3315       _fam_cells=DataArrayInt::New();
3316       _fam_cells->alloc(nbOfElt,1);
3317       MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
3318     }
3319   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
3320   if(nbOfElt>0)
3321     {
3322       _num_cells=DataArrayInt::New();
3323       _num_cells->alloc(nbOfElt,1);
3324       MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
3325     }
3326   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
3327   if(nbOfElt>0)
3328     {
3329       _names_cells=DataArrayAsciiChar::New();
3330       _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
3331       MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
3332       _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
3333     }
3334   nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
3335   if(nbOfElt>0)
3336     {
3337       _names_nodes=DataArrayAsciiChar::New();
3338       _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
3339       MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
3340       _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
3341     }
3342 }
3343
3344 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
3345 {
3346   int meshDim=getStructuredMesh()->getMeshDimension();
3347   med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
3348   //
3349   if((const DataArrayInt *)_fam_cells)
3350     MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
3351   if((const DataArrayInt *)_fam_nodes)
3352     MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
3353   if((const DataArrayInt *)_num_cells)
3354     MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
3355   if((const DataArrayInt *)_num_nodes)
3356     MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
3357   if((const DataArrayAsciiChar *)_names_cells)
3358     {
3359       if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
3360         {
3361           std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
3362           oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
3363           throw INTERP_KERNEL::Exception(oss.str().c_str());
3364         }
3365       MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
3366     }
3367   if((const DataArrayAsciiChar *)_names_nodes)
3368     {
3369       if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
3370         {
3371           std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
3372           oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
3373           throw INTERP_KERNEL::Exception(oss.str().c_str());
3374         }
3375       MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
3376     }
3377   //
3378   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
3379 }
3380
3381 MEDFileCMesh *MEDFileCMesh::New()
3382 {
3383   return new MEDFileCMesh;
3384 }
3385
3386 MEDFileCMesh *MEDFileCMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
3387 {
3388   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
3389   if(ms.empty())
3390     {
3391       std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
3392       throw INTERP_KERNEL::Exception(oss.str().c_str());
3393     }
3394   MEDFileUtilities::CheckFileForRead(fileName);
3395   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3396   int dt,it;
3397   ParaMEDMEM::MEDCouplingMeshType meshType;
3398   std::string dummy2;
3399   MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
3400   return new MEDFileCMesh(fid,ms.front().c_str(),dt,it);
3401 }
3402
3403 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3404 {
3405   MEDFileUtilities::CheckFileForRead(fileName);
3406   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3407   return new MEDFileCMesh(fid,mName,dt,it);
3408 }
3409
3410 std::size_t MEDFileCMesh::getHeapMemorySize() const
3411 {
3412   std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
3413   if((const MEDCouplingCMesh *)_cmesh)
3414     ret+=_cmesh->getHeapMemorySize();
3415   return ret;
3416 }
3417
3418 int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
3419 {
3420   if(!((const MEDCouplingCMesh*)_cmesh))
3421     throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
3422   return _cmesh->getMeshDimension();
3423 }
3424
3425 std::string MEDFileCMesh::simpleRepr() const
3426 {
3427   return MEDFileStructuredMesh::simpleRepr();
3428 }
3429
3430 std::string MEDFileCMesh::advancedRepr() const
3431 {
3432   return simpleRepr();
3433 }
3434
3435 MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
3436 {
3437   MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
3438   return ret.retn();
3439 }
3440
3441 MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
3442 {
3443   MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
3444   if((const MEDCouplingCMesh*)_cmesh)
3445     ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
3446   ret->deepCpyAttributes();
3447   return ret.retn();
3448 }
3449
3450 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3451 {
3452   if(!MEDFileStructuredMesh::isEqual(other,eps,what))
3453     return false;
3454   const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
3455   if(!otherC)
3456     {
3457       what="Mesh types differ ! This is cartesian and other is NOT !";
3458       return false;
3459     }
3460   clearNonDiscrAttributes();
3461   otherC->clearNonDiscrAttributes();
3462   const MEDCouplingCMesh *coo1=_cmesh;
3463   const MEDCouplingCMesh *coo2=otherC->_cmesh;
3464   if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
3465     {
3466       what="Mismatch of cartesian meshes ! One is defined and not other !";
3467       return false;
3468     }
3469   if(coo1)
3470     {
3471       bool ret=coo1->isEqual(coo2,eps);
3472       if(!ret)
3473         {
3474           what="cartesian meshes differ !";
3475           return false;
3476         }
3477     }
3478   return true;
3479 }
3480
3481 void MEDFileCMesh::clearNonDiscrAttributes() const
3482 {
3483   MEDFileStructuredMesh::clearNonDiscrAttributes();
3484   MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
3485 }
3486
3487 MEDFileCMesh::MEDFileCMesh()
3488 {
3489 }
3490
3491 MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3492 try
3493   {
3494     loadCMeshFromFile(fid,mName,dt,it);
3495   }
3496 catch(INTERP_KERNEL::Exception& e)
3497   {
3498     throw e;
3499   }
3500
3501 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3502 {
3503   ParaMEDMEM::MEDCouplingMeshType meshType;
3504   int dummy0,dummy1;
3505   std::string dtunit;
3506   int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
3507   if(meshType!=CARTESIAN)
3508     {
3509       std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
3510       throw INTERP_KERNEL::Exception(oss.str().c_str());
3511     }
3512   MEDFileCMeshL2 loaderl2;
3513   loaderl2.loadAll(fid,mid,mName,dt,it);
3514   MEDCouplingCMesh *mesh=loaderl2.getMesh();
3515   mesh->incrRef();
3516   _cmesh=mesh;
3517   loadStrMeshFromFile(&loaderl2,fid,mName,dt,it);
3518 }
3519
3520 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
3521 {
3522   synchronizeTinyInfoOnLeaves();
3523   return _cmesh;
3524 }
3525
3526 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
3527 {
3528   synchronizeTinyInfoOnLeaves();
3529   return _cmesh;
3530 }
3531
3532 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
3533 {
3534   dealWithTinyInfo(m);
3535   if(m)
3536     m->incrRef();
3537   _cmesh=m;
3538 }
3539
3540 void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
3541 {
3542   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3543   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3544   INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
3545   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3546   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3547   MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
3548   int spaceDim=_cmesh->getSpaceDimension();
3549   int meshDim=_cmesh->getMeshDimension();
3550   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3551   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3552   for(int i=0;i<spaceDim;i++)
3553     {
3554       std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
3555       std::string c,u;
3556       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3557       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
3558       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
3559     }
3560   MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
3561   MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
3562   for(int i=0;i<spaceDim;i++)
3563     {
3564       const DataArrayDouble *da=_cmesh->getCoordsAt(i);
3565       MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
3566     }
3567   //
3568   MEDFileStructuredMesh::writeStructuredLL(fid,maa);
3569 }
3570
3571 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
3572 {
3573   const MEDCouplingCMesh *cmesh=_cmesh;
3574   if(!cmesh)
3575     return;
3576   (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
3577   (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
3578   (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
3579   (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
3580 }
3581
3582 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
3583 {
3584   return new MEDFileCurveLinearMesh;
3585 }
3586
3587 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
3588 {
3589   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
3590   if(ms.empty())
3591     {
3592       std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
3593       throw INTERP_KERNEL::Exception(oss.str().c_str());
3594     }
3595   MEDFileUtilities::CheckFileForRead(fileName);
3596   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3597   int dt,it;
3598   ParaMEDMEM::MEDCouplingMeshType meshType;
3599   std::string dummy2;
3600   MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
3601   return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it);
3602 }
3603
3604 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3605 {
3606   MEDFileUtilities::CheckFileForRead(fileName);
3607   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3608   return new MEDFileCurveLinearMesh(fid,mName,dt,it);
3609 }
3610
3611 std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
3612 {
3613   std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
3614   if((const MEDCouplingCurveLinearMesh *)_clmesh)
3615     ret+=_clmesh->getHeapMemorySize();
3616   return ret;
3617 }
3618
3619 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
3620 {
3621   MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
3622   return ret.retn();
3623 }
3624
3625 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
3626 {
3627   MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
3628   if((const MEDCouplingCurveLinearMesh*)_clmesh)
3629     ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
3630   ret->deepCpyAttributes();
3631   return ret.retn();
3632 }
3633
3634 int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
3635 {
3636   if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
3637     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
3638   return _clmesh->getMeshDimension();
3639 }
3640
3641 std::string MEDFileCurveLinearMesh::simpleRepr() const
3642 {
3643   return MEDFileStructuredMesh::simpleRepr();
3644 }
3645
3646 std::string MEDFileCurveLinearMesh::advancedRepr() const
3647 {
3648   return simpleRepr();
3649 }
3650
3651 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3652 {
3653   if(!MEDFileStructuredMesh::isEqual(other,eps,what))
3654     return false;
3655   const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
3656   if(!otherC)
3657     {
3658       what="Mesh types differ ! This is curve linear and other is NOT !";
3659       return false;
3660     }
3661   clearNonDiscrAttributes();
3662   otherC->clearNonDiscrAttributes();
3663   const MEDCouplingCurveLinearMesh *coo1=_clmesh;
3664   const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
3665   if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
3666     {
3667       what="Mismatch of curve linear meshes ! One is defined and not other !";
3668       return false;
3669     }
3670   if(coo1)
3671     {
3672       bool ret=coo1->isEqual(coo2,eps);
3673       if(!ret)
3674         {
3675           what="curve linear meshes differ !";
3676           return false;
3677         }
3678     }
3679   return true;
3680 }
3681
3682 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
3683 {
3684   MEDFileStructuredMesh::clearNonDiscrAttributes();
3685   MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
3686 }
3687
3688 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
3689 {
3690   const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
3691   if(!clmesh)
3692     return;
3693   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
3694   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
3695   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
3696   (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
3697 }
3698
3699 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
3700 {
3701   synchronizeTinyInfoOnLeaves();
3702   return _clmesh;
3703 }
3704
3705 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
3706 {
3707   dealWithTinyInfo(m);
3708   if(m)
3709     m->incrRef();
3710   _clmesh=m;
3711 }
3712
3713 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
3714 {
3715   synchronizeTinyInfoOnLeaves();
3716   return _clmesh;
3717 }
3718
3719 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
3720 {
3721 }
3722
3723 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3724 try
3725   {
3726     loadCLMeshFromFile(fid,mName,dt,it);
3727   }
3728 catch(INTERP_KERNEL::Exception& e)
3729   {
3730     throw e;
3731   }
3732
3733 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
3734 {
3735   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3736   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3737   INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
3738   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3739   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3740   MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
3741   int spaceDim=_clmesh->getSpaceDimension();
3742   int meshDim=_clmesh->getMeshDimension();
3743   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3744   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3745   const DataArrayDouble *coords=_clmesh->getCoords();
3746   if(!coords)
3747     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
3748   for(int i=0;i<spaceDim;i++)
3749     {
3750       std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
3751       std::string c,u;
3752       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3753       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
3754       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
3755     }
3756   MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
3757   MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
3758   std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
3759   MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
3760   
3761   MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
3762   //
3763   MEDFileStructuredMesh::writeStructuredLL(fid,maa);
3764 }
3765
3766 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3767 {
3768   ParaMEDMEM::MEDCouplingMeshType meshType;
3769   int dummy0,dummy1;
3770   std::string dtunit;
3771   int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
3772   if(meshType!=CURVE_LINEAR)
3773     {
3774       std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
3775       throw INTERP_KERNEL::Exception(oss.str().c_str());
3776     }
3777   MEDFileCLMeshL2 loaderl2;
3778   loaderl2.loadAll(fid,mid,mName,dt,it);
3779   MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
3780   mesh->incrRef();
3781   _clmesh=mesh;
3782   loadStrMeshFromFile(&loaderl2,fid,mName,dt,it);
3783 }
3784
3785 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
3786 {
3787   return new MEDFileMeshMultiTS;
3788 }
3789
3790 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
3791 {
3792   return new MEDFileMeshMultiTS(fileName);
3793 }
3794
3795 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
3796 {
3797   return new MEDFileMeshMultiTS(fileName,mName);
3798 }
3799
3800 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
3801 {
3802   MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
3803   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
3804   std::size_t i=0;
3805   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
3806     if((const MEDFileMesh *)*it)
3807       meshOneTs[i]=(*it)->deepCpy();
3808   ret->_mesh_one_ts=meshOneTs;
3809   return ret.retn();
3810 }
3811
3812 std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
3813 {
3814   std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
3815   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
3816     ret+=(*it)->getHeapMemorySize();
3817   return ret;
3818 }
3819
3820 const char *MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
3821 {
3822   if(_mesh_one_ts.empty())
3823     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
3824   return _mesh_one_ts[0]->getName();
3825 }
3826
3827 void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
3828 {
3829   std::string oldName(getName());
3830   std::vector< std::pair<std::string,std::string> > v(1);
3831   v[0].first=oldName; v[0].second=newMeshName;
3832   changeNames(v);
3833 }
3834
3835 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
3836 {
3837   bool ret=false;
3838   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
3839     {
3840       MEDFileMesh *cur(*it);
3841       if(cur)
3842         ret=cur->changeNames(modifTab) || ret;
3843     }
3844   return ret;
3845 }
3846
3847 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
3848 {
3849   if(_mesh_one_ts.empty())
3850     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
3851   return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
3852 }
3853
3854 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
3855 {
3856   if(!mesh1TimeStep)
3857     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
3858   _mesh_one_ts.resize(1);
3859   mesh1TimeStep->incrRef();
3860   //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
3861   _mesh_one_ts[0]=mesh1TimeStep;
3862 }
3863
3864 void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
3865 {
3866   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
3867     {
3868       (*it)->copyOptionsFrom(*this);
3869       (*it)->write(fid);
3870     }
3871 }
3872
3873 void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
3874 {
3875   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
3876   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
3877   std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
3878   MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
3879   write(fid);
3880 }
3881
3882 void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
3883 {//for the moment to be improved
3884   _mesh_one_ts.resize(1);
3885   _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
3886 }
3887
3888 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
3889 {
3890 }
3891
3892 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
3893 try
3894   {
3895     std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
3896     if(ms.empty())
3897     {
3898       std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
3899       throw INTERP_KERNEL::Exception(oss.str().c_str());
3900     }
3901     MEDFileUtilities::CheckFileForRead(fileName);
3902     MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
3903     int dt,it;
3904     ParaMEDMEM::MEDCouplingMeshType meshType;
3905     std::string dummy2;
3906     MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
3907     loadFromFile(fileName,ms.front().c_str());
3908   }
3909 catch(INTERP_KERNEL::Exception& e)
3910   {
3911     throw e;
3912   }
3913
3914 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
3915 try
3916   {
3917     loadFromFile(fileName,mName);
3918   }
3919 catch(INTERP_KERNEL::Exception& e)
3920   {
3921     throw e;
3922   }
3923
3924 MEDFileMeshes *MEDFileMeshes::New()
3925 {
3926   return new MEDFileMeshes;
3927 }
3928
3929 MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
3930 {
3931   return new MEDFileMeshes(fileName);
3932 }
3933
3934 void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
3935 {
3936   checkCoherency();
3937   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
3938     {
3939       (*it)->copyOptionsFrom(*this);
3940       (*it)->write(fid);
3941     }
3942 }
3943
3944 void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
3945 {
3946   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
3947   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
3948   std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
3949   MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
3950   checkCoherency();
3951   write(fid);
3952 }
3953
3954 int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
3955 {
3956   return _meshes.size();
3957 }
3958
3959 MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
3960 {
3961   return new MEDFileMeshesIterator(this);
3962 }
3963
3964 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
3965 {
3966   if(i<0 || i>=(int)_meshes.size())
3967     {
3968       std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
3969       throw INTERP_KERNEL::Exception(oss.str().c_str());
3970     }
3971   return _meshes[i]->getOneTimeStep();
3972 }
3973
3974 MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
3975 {
3976   std::vector<std::string> ms=getMeshesNames();
3977   std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
3978   if(it==ms.end())
3979     {
3980       std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh  \"" << mname << "\" does not exist in this ! Existing are : ";
3981       std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
3982       throw INTERP_KERNEL::Exception(oss.str().c_str());
3983     }
3984   return getMeshAtPos((int)std::distance(ms.begin(),it));
3985 }
3986
3987 std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
3988 {
3989   std::vector<std::string> ret(_meshes.size());
3990   int i=0;
3991   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
3992     {
3993       const MEDFileMeshMultiTS *f=(*it);
3994       if(f)
3995         {
3996           ret[i]=f->getName();
3997         }
3998       else
3999         {
4000           std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
4001           throw INTERP_KERNEL::Exception(oss.str().c_str());
4002         }
4003     }
4004   return ret;
4005 }
4006
4007 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
4008 {
4009   bool ret=false;
4010   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
4011     {
4012       MEDFileMeshMultiTS *cur(*it);
4013       if(cur)
4014         ret=cur->changeNames(modifTab) || ret;
4015     }
4016   return ret;
4017 }
4018
4019 void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
4020 {
4021   _meshes.resize(newSize);
4022 }
4023
4024 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
4025 {
4026   if(!mesh)
4027     throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
4028   MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
4029   elt->setOneTimeStep(mesh);
4030   _meshes.push_back(elt);
4031 }
4032
4033 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
4034 {
4035   if(!mesh)
4036     throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
4037   if(i>=(int)_meshes.size())
4038     _meshes.resize(i+1);
4039   MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
4040   elt->setOneTimeStep(mesh);
4041   _meshes[i]=elt;
4042 }
4043
4044 void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
4045 {
4046   if(i<0 || i>=(int)_meshes.size())
4047     {
4048       std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
4049       throw INTERP_KERNEL::Exception(oss.str().c_str());
4050     }
4051   _meshes.erase(_meshes.begin()+i);
4052 }
4053
4054 void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
4055 {
4056   std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4057   int i=0;
4058   _meshes.resize(ms.size());
4059   for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4060     _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str());
4061 }
4062
4063 MEDFileMeshes::MEDFileMeshes()
4064 {
4065 }
4066
4067 MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
4068 try
4069   {
4070     loadFromFile(fileName);
4071   }
4072 catch(INTERP_KERNEL::Exception& e)
4073   {
4074   }
4075
4076 MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
4077 {
4078   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
4079   std::size_t i=0;
4080   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
4081     if((const MEDFileMeshMultiTS *)*it)
4082       meshes[i]=(*it)->deepCpy();
4083   MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
4084   ret->_meshes=meshes;
4085   return ret.retn();
4086 }
4087
4088 std::size_t MEDFileMeshes::getHeapMemorySize() const
4089 {
4090   std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
4091   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
4092     if((const MEDFileMeshMultiTS*)*it)
4093       ret+=(*it)->getHeapMemorySize();
4094   return ret; 
4095 }
4096
4097 std::string MEDFileMeshes::simpleRepr() const
4098 {
4099   std::ostringstream oss;
4100   oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
4101   simpleReprWithoutHeader(oss);
4102   return oss.str();
4103 }
4104
4105 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
4106 {
4107   int nbOfMeshes=getNumberOfMeshes();
4108   oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
4109   std::vector<std::string> mns=getMeshesNames();
4110   for(int i=0;i<nbOfMeshes;i++)
4111     oss << "  - #" << i << " \"" << mns[i] << "\"\n";
4112 }
4113
4114 void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
4115 {
4116   static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
4117   int i=0;
4118   std::set<std::string> s;
4119   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
4120     {
4121       const MEDFileMeshMultiTS *elt=(*it);
4122       if(!elt)
4123         {
4124           std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
4125           throw INTERP_KERNEL::Exception(oss.str().c_str());
4126         }
4127       std::size_t sz=s.size();
4128       s.insert(std::string((*it)->getName()));
4129       if(s.size()==sz)
4130         {
4131           std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
4132           throw INTERP_KERNEL::Exception(oss.str().c_str());
4133         }
4134     }
4135 }
4136
4137 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
4138 {
4139   if(ms)
4140     {
4141       ms->incrRef();
4142       _nb_iter=ms->getNumberOfMeshes();
4143     }
4144 }
4145
4146 MEDFileMeshesIterator::~MEDFileMeshesIterator()
4147 {
4148 }
4149
4150 MEDFileMesh *MEDFileMeshesIterator::nextt()
4151 {
4152   if(_iter_id<_nb_iter)
4153     {
4154       MEDFileMeshes *ms(_ms);
4155       if(ms)
4156         return ms->getMeshAtPos(_iter_id++);
4157       else
4158         return 0;
4159     }
4160   else
4161     return 0;
4162 }