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