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