Salome HOME
Merge branch 'master' of https://codev-tuleap.cea.fr/plugins/git/salome/medcoupling
[tools/medcoupling.git] / src / MEDLoader / MEDFileEquivalence.cxx
1 // Copyright (C) 2007-2020  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, or (at your option) any later version.
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 (EDF R&D)
20
21 #include "MEDFileEquivalence.hxx"
22 #include "MEDFileSafeCaller.txx"
23 #include "MEDCouplingMemArray.hxx"
24 #include "MEDCouplingMemArray.txx"
25 #include "MEDLoaderBase.hxx"
26 #include "MEDFileMesh.hxx"
27 #include "InterpKernelAutoPtr.hxx"
28
29 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
30 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
31 extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE];
32 extern med_geometry_type typmainoeud[1];
33
34 using namespace MEDCoupling;
35
36 MEDFileEquivalencePair *MEDFileEquivalencePair::Load(MEDFileEquivalences *father, med_idt fid, const std::string& name, const std::string &desc)
37 {
38   if(!father)
39     throw INTERP_KERNEL::Exception("MEDFileEquivalencePair::Load : father is NULL ! Should not !");
40   MCAuto<MEDFileEquivalencePair> ret(new MEDFileEquivalencePair(father,name,desc));
41   ret->load(fid);
42   return ret.retn();
43 }
44
45 void MEDFileEquivalencePair::writeLL(med_idt fid) const
46 {
47   std::string meshName(getFather()->getMeshName());
48   INTERP_KERNEL::AutoPtr<char> meshName2(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
49   INTERP_KERNEL::AutoPtr<char> name(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
50   INTERP_KERNEL::AutoPtr<char> desc(MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE));
51   MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,meshName2,getFather()->getMesh()->getTooLongStrPolicy());
52   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,name,getFather()->getMesh()->getTooLongStrPolicy());
53   MEDLoaderBase::safeStrCpy(_description.c_str(),MED_COMMENT_SIZE,desc,getFather()->getMesh()->getTooLongStrPolicy());
54   MEDFILESAFECALLERWR0(MEDequivalenceCr,(fid,meshName2,name,desc));
55   const MEDFileEquivalenceCell *cell(_cell);
56   if(cell)
57     cell->writeLL(fid);
58   const MEDFileEquivalenceNode *node(_node);
59   if(node)
60     node->writeLL(fid);
61 }
62
63 const MEDFileMesh *MEDFileEquivalencePair::getMesh() const
64 {
65   return getFather()->getMesh();
66 }
67
68 MEDFileMesh *MEDFileEquivalencePair::getMesh()
69 {
70   return getFather()->getMesh();
71 }
72
73 MEDFileEquivalencePair *MEDFileEquivalencePair::deepCopy(MEDFileEquivalences *father) const
74 {
75   MCAuto<MEDFileEquivalencePair> ret(new MEDFileEquivalencePair(father,_name,_description));
76   const MEDFileEquivalenceCell *cell(_cell);
77   if(cell)
78     ret->_cell=cell->deepCopy(const_cast<MEDFileEquivalencePair *>(this));
79   const MEDFileEquivalenceNode *node(_node);
80   if(node)
81     ret->_node=node->deepCopy(const_cast<MEDFileEquivalencePair *>(this));
82   return ret.retn();
83 }
84
85 bool MEDFileEquivalencePair::isEqual(const MEDFileEquivalencePair *other, std::string& what) const
86 {
87   if(_name!=other->_name)
88     {
89       std::ostringstream oss; oss << "Names differs : " << _name << " != " << other->_name << " !";
90       what=oss.str();
91       return false;
92     }
93   if(_description!=other->_description)
94     {
95        std::ostringstream oss; oss << "Description differs : " << _description << " != " << other->_description << " !";
96        what=oss.str();
97        return false;
98     }
99   const MEDFileEquivalenceCell *c1(_cell),*c2(other->_cell);
100   if((c1 && !c2) || (!c1 && c2))
101     {
102       std::ostringstream oss; oss << "Cell def of Equiv " << _name << " are defined for this and not for other (or reversely) !";
103       what=oss.str();
104       return false;
105     }
106   if(c1 && c2)
107     if(!c1->isEqual(c2,what))
108       return false;
109   const MEDFileEquivalenceNode *n1(_node),*n2(other->_node);
110   if((n1 && !n2) || (!n1 && n2))
111     {
112       std::ostringstream oss; oss << "Node def of Equiv " << _name << " are defined for this and not for other (or reversely) !";
113       what=oss.str();
114       return false;
115     }
116   if(n1 && n2)
117     if(!n1->isEqual(n2,what))
118       return false;
119   return true;
120 }
121
122 void MEDFileEquivalencePair::getRepr(std::ostream& oss) const
123 {
124   const MEDFileEquivalenceNode *node(_node);
125   const MEDFileEquivalenceCell *cell(_cell);
126   oss << std::endl << "  name of equivalence : " << _name << std::endl;
127   oss << "  description of equivalence : " << _description << std::endl;
128   oss << "  Node : ";
129   if(!node)
130     oss << "None" << std::endl;
131   else
132     node->getRepr(oss);
133   oss << "  Cell : ";
134   if(!cell)
135     oss << "None" << std::endl;
136   else
137     cell->getRepr(oss);
138 }
139
140 MEDFileEquivalencePair *MEDFileEquivalencePair::New(MEDFileEquivalences *father, const std::string& name)
141 {
142   return new MEDFileEquivalencePair(father,name,std::string());
143 }
144
145 std::vector<const BigMemoryObject *> MEDFileEquivalencePair::getDirectChildrenWithNull() const
146 {
147   std::vector<const BigMemoryObject *> ret(2);
148   ret[0]=_cell; ret[1]=_node;
149   return ret;
150 }
151
152 void MEDFileEquivalencePair::setArray(int meshDimRelToMaxExt, DataArrayInt *da)
153 {
154   if(meshDimRelToMaxExt>1)
155     throw INTERP_KERNEL::Exception("MEDFileEquivalencePair::setArray : meshDimRelToMaxExt must be in [1,0,-1,-2,-3] at most !");
156   if(meshDimRelToMaxExt==1)
157     {
158       MEDFileEquivalenceNode *node(_node);
159       if(!node)
160         {
161           _node=new MEDFileEquivalenceNode(this,0);
162           node=_node;
163         }
164       node->setArray(da);
165     }
166   else
167     {
168       MEDFileEquivalenceCell *cell(_cell);
169       if(!cell)
170         {
171           _cell=new MEDFileEquivalenceCell(this);
172           cell=_cell;
173         }
174       cell->setArray(meshDimRelToMaxExt,da);
175     }
176 }
177
178 /*!
179  * The returned pointer is a borrowed pointer.
180  */
181 MEDFileEquivalenceCell *MEDFileEquivalencePair::initCell()
182 {
183   _cell=new MEDFileEquivalenceCell(this);
184   return _cell;
185 }
186
187 /*!
188  * The returned pointer is a borrowed pointer.
189  */
190 MEDFileEquivalenceNode *MEDFileEquivalencePair::initNode()
191 {
192   _node=new MEDFileEquivalenceNode(this,0);
193   return _node;
194 }
195
196 std::size_t MEDFileEquivalencePair::getHeapMemorySizeWithoutChildren() const
197 {
198   return 0;
199 }
200
201 void MEDFileEquivalencePair::load(med_idt fid)
202 {
203   std::string meshName(_father->getMeshName());
204   int dt,it;
205   _father->getDtIt(dt,it);
206   med_int ncor;
207   MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceSize,(fid,meshName.c_str(),_name.c_str(),dt,it,MED_NODE,MED_NONE,&ncor));
208   if(ncor>0)
209     {
210       MCAuto<DataArrayMedInt> da(DataArrayMedInt::New());
211       da->alloc(ncor*2);
212       MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceRd,(fid,meshName.c_str(),_name.c_str(),dt,it,MED_NODE,MED_NONE,da->getPointer()));
213       da->applyLin(1,-1);
214       da->rearrange(2);
215       MCAuto<MEDFileEquivalenceNode> node(new MEDFileEquivalenceNode(this,FromMedIntArray<int>(da)));
216       _node=node;
217     }
218   _cell=MEDFileEquivalenceCell::Load(fid,this);
219 }
220
221 std::vector<const BigMemoryObject *> MEDFileEquivalences::getDirectChildrenWithNull() const
222 {
223   std::size_t sz(_equ.size());
224   std::vector<const BigMemoryObject *> ret(sz);
225   for(std::size_t i=0;i<sz;i++)
226     ret[i]=_equ[i];
227   return ret;
228 }
229
230 std::size_t MEDFileEquivalences::getHeapMemorySizeWithoutChildren() const
231 {
232   return sizeof(MEDFileEquivalences)+_equ.capacity()*sizeof(MEDFileEquivalencePair);
233 }
234
235 void MEDFileEquivalences::getDtIt(int &dt, int &it) const
236 {
237   dt=_owner->getIteration(); it=_owner->getOrder();
238 }
239
240 std::string MEDFileEquivalences::getMeshName() const
241 {
242   return _owner->getName();
243 }
244
245 void MEDFileEquivalences::pushEquivalence(MEDFileEquivalencePair *elt)
246 {
247   MCAuto<MEDFileEquivalencePair> elta(elt);
248   if(elt)
249     elt->incrRef();
250   _equ.push_back(elta);
251 }
252
253 MEDFileEquivalencePair *MEDFileEquivalences::getEquivalence(int i)
254 {
255   int sz(size());
256   if(i<0 || i>=sz)
257     {
258       std::ostringstream oss; oss << "MEDFileEquivalences::getEquivalence : invalid id ! Must be in [0," << sz << ") !";
259       throw INTERP_KERNEL::Exception(oss.str().c_str());
260     }
261   return _equ[i];
262 }
263
264 MEDFileEquivalencePair *MEDFileEquivalences::getEquivalenceWithName(const std::string& name)
265 {
266   for(std::vector< MCAuto<MEDFileEquivalencePair> >::iterator it=_equ.begin();it!=_equ.end();it++)
267     {
268       MEDFileEquivalencePair *elt(*it);
269       if(elt)
270         {
271           if(elt->getName()==name)
272             return elt;
273         }
274     }
275   std::ostringstream oss; oss << "MEDFileEquivalences::getEquivalenceWithName : no equivalence with name \"" << name << "\" ! Must be in [ ";
276   std::vector<std::string> eqs(getEquivalenceNames());
277   std::copy(eqs.begin(),eqs.end(),std::ostream_iterator<std::string>(oss,", "));
278   oss << "] !";
279   throw INTERP_KERNEL::Exception(oss.str().c_str());
280 }
281
282 int MEDFileEquivalences::size() const
283 {
284   return (int)_equ.size();
285 }
286
287 std::vector<std::string> MEDFileEquivalences::getEquivalenceNames() const
288 {
289   std::vector<std::string> ret;
290   for(std::vector< MCAuto<MEDFileEquivalencePair> >::const_iterator it=_equ.begin();it!=_equ.end();it++)
291     {
292       const MEDFileEquivalencePair *elt(*it);
293       if(elt)
294         {
295           ret.push_back(elt->getName());
296         }
297     }
298   return ret;
299 }
300
301 MEDFileEquivalencePair *MEDFileEquivalences::appendEmptyEquivalenceWithName(const std::string& name)
302 {
303   MCAuto<MEDFileEquivalencePair> elt(MEDFileEquivalencePair::New(this,name));
304   _equ.push_back(elt);
305   return elt;
306 }
307
308 MEDFileEquivalences *MEDFileEquivalences::deepCopy(MEDFileMesh *owner) const
309 {
310   MCAuto<MEDFileEquivalences> ret(new MEDFileEquivalences(owner));
311   ret->deepCpyFrom(*this);
312   return ret.retn();
313 }
314
315 bool MEDFileEquivalences::isEqual(const MEDFileEquivalences *other, std::string& what) const
316 {
317   std::size_t sz(_equ.size());
318   if(sz!=other->_equ.size())
319     {
320       what="Equivalences differs : not same number !";
321       return false;
322     }
323   for(std::size_t i=0;i<sz;i++)
324     {
325       const MEDFileEquivalencePair *thisp(_equ[i]),*otherp(other->_equ[i]);
326       if(!thisp && !otherp)
327         continue;
328       if(thisp && otherp)
329         {
330           if(!thisp->isEqual(otherp,what))
331             {
332               std::ostringstream oss; oss << "At Eq #" << i << " there is a difference !";
333               what=oss.str()+what;
334               return false;
335             }
336         }
337       else
338         {
339           std::ostringstream oss; oss << "At Eq #" << i << " defined in this not is other (or reversely) !";
340           what=oss.str()+what;
341           return false;
342         }
343     }
344   return true;
345 }
346
347 void MEDFileEquivalences::getRepr(std::ostream& oss) const
348 {
349   std::size_t ii(0);
350   for(std::vector< MCAuto<MEDFileEquivalencePair> >::const_iterator it=_equ.begin();it!=_equ.end();it++,ii++)
351     {
352       const MEDFileEquivalencePair *elt(*it);
353       oss << "Equivalence #" << ii << " : " ;
354       if(elt)
355         elt->getRepr(oss);
356       else
357         oss << "None" << std::endl;
358     }
359 }
360
361 void MEDFileEquivalences::killEquivalenceWithName(const std::string& name)
362 {
363   std::vector< MCAuto<MEDFileEquivalencePair> >::iterator it(_equ.begin());
364   for(;it!=_equ.end();it++)
365     {
366       const MEDFileEquivalencePair *elt(*it);
367       if(elt && elt->getName()==name)
368         break;
369     }
370   if(it==_equ.end())
371     {
372       std::ostringstream oss; oss << "MEDFileEquivalences::killEquivalenceWithName : Equivalence with name \"" << name << "\" not found !";
373       throw INTERP_KERNEL::Exception(oss.str().c_str());
374     }
375   _equ.erase(it);
376 }
377
378 void MEDFileEquivalences::killEquivalenceAt(int i)
379 {
380   int sz(size());
381   if(i<0 || i>=sz)
382     {
383       std::ostringstream oss; oss << "MEDFileEquivalences::killEquivalenceAt : Id must be in [0," << sz << ") !";
384       throw INTERP_KERNEL::Exception(oss.str().c_str());
385     }
386   std::vector< MCAuto<MEDFileEquivalencePair> >::iterator it(_equ.begin());
387   for(int j=0;j<i;it++,j++);
388   _equ.erase(it);
389 }
390
391 void MEDFileEquivalences::clear()
392 {
393   _equ.clear();
394 }
395
396 void MEDFileEquivalences::writeLL(med_idt fid) const
397 {
398   for(std::vector< MCAuto<MEDFileEquivalencePair> >::const_iterator it=_equ.begin();it!=_equ.end();it++)
399     {
400       const MEDFileEquivalencePair *elt(*it);
401       if(elt)
402         elt->writeLL(fid);
403     }
404 }
405
406 int MEDFileEquivalences::PresenceOfEquivalences(med_idt fid, const std::string& meshName)
407 {
408   med_int nequ(MEDnEquivalence(fid,meshName.c_str()));
409   return FromMedInt<int>(nequ);
410 }
411
412 MEDFileEquivalences *MEDFileEquivalences::Load(med_idt fid, int nbOfEq, MEDFileMesh *owner)
413 {
414   MCAuto<MEDFileEquivalences> ret(new MEDFileEquivalences(owner));
415   if(!owner)
416     throw INTERP_KERNEL::Exception("MEDFileEquivalences::Load : owner is NULL !");
417   std::string meshName(owner->getName());
418   for(int i=0;i<nbOfEq;i++)
419     {
420       INTERP_KERNEL::AutoPtr<char> equ(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
421       INTERP_KERNEL::AutoPtr<char> desc(MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE));
422       med_int nstep,nocstpncor;
423       MEDFILESAFECALLERRD0(MEDequivalenceInfo,(fid,meshName.c_str(),i+1,equ,desc,&nstep,&nocstpncor));
424       std::string eqName(MEDLoaderBase::buildStringFromFortran(equ,MED_NAME_SIZE)),eqDescName(MEDLoaderBase::buildStringFromFortran(desc,MED_COMMENT_SIZE));
425       MCAuto<MEDFileEquivalencePair> eqv(MEDFileEquivalencePair::Load(ret,fid,eqName,eqDescName));
426       ret->pushEquivalence(eqv);
427     }
428   return ret.retn();
429 }
430
431 void MEDFileEquivalences::CheckDataArray(const DataArrayInt *data)
432 {
433   if(!data)
434     return;
435   data->checkAllocated();
436   if(data->getNumberOfComponents()!=2)
437     {
438       std::ostringstream oss; oss << "MEDFileEquivalences::CheckDataArray : Input DataArray must have 2 components !";
439       throw INTERP_KERNEL::Exception(oss.str().c_str());
440     }
441 }
442
443 void MEDFileEquivalences::deepCpyFrom(const MEDFileEquivalences& other)
444 {
445   for(std::vector< MCAuto<MEDFileEquivalencePair> >::const_iterator it=other._equ.begin();it!=other._equ.end();it++)
446     {
447       const MEDFileEquivalencePair *elt(*it);
448       MCAuto<MEDFileEquivalencePair> eltCpy;
449       if(elt)
450         {
451           eltCpy=elt->deepCopy(this);
452         }
453       _equ.push_back(eltCpy);
454     }
455 }
456
457 MEDFileEquivalenceBase::MEDFileEquivalenceBase(MEDFileEquivalencePair *father):_father(father)
458 {
459 }
460
461 MEDFileEquivalenceData::MEDFileEquivalenceData(MEDFileEquivalencePair *owner, DataArrayInt *data):MEDFileEquivalenceBase(owner),_data(data)
462 {
463   if(data)
464     data->incrRef();
465 }
466
467 void MEDFileEquivalenceData::setArray(DataArrayInt *data)
468 {
469   MEDFileEquivalences::CheckDataArray(data);
470   _data=data;
471   if(data)
472     data->incrRef();
473 }
474
475 std::vector<const BigMemoryObject *> MEDFileEquivalenceData::getDirectChildrenWithNull() const
476 {
477   std::vector<const BigMemoryObject *> ret(1);
478   ret[0]=_data;
479   return ret;
480 }
481
482 bool MEDFileEquivalenceData::isEqual(const MEDFileEquivalenceData *other, std::string& what) const
483 {
484   const DataArrayInt *d1(_data),*d2(other->_data);
485   if((!d1 && d2) || (d1 && !d2))
486     {
487       what="Data array is defined in this not in other (or reversely) !";
488       return false;
489     }
490   if(d1 && d2)
491     {
492       if(!d1->isEqualIfNotWhy(*d2,what))
493         return false;
494     }
495   return true;
496 }
497
498 void MEDFileEquivalenceData::writeAdvanced(med_idt fid, med_entity_type medtype, med_geometry_type medgt) const
499 {
500   
501   const DataArrayInt *da(getArray());
502   if(!da)
503     return ;
504   MEDFileEquivalences::CheckDataArray(da);
505   const MEDFileMesh *mesh(getFather()->getMesh());
506   int dt,it;
507   mesh->getTime(dt,it);
508   std::string meshName(mesh->getName());
509   std::string equName(getFather()->getName());
510   INTERP_KERNEL::AutoPtr<char> meshName2(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
511   INTERP_KERNEL::AutoPtr<char> name(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
512   MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,meshName2,getFather()->getMesh()->getTooLongStrPolicy());
513   MEDLoaderBase::safeStrCpy(equName.c_str(),MED_NAME_SIZE,name,getFather()->getMesh()->getTooLongStrPolicy());
514   MCAuto<DataArrayMedInt> da2(DataArrayMedInt::Copy(da)); da2->rearrange(1); da2->applyLin(1,1); da2->rearrange(2);
515   MEDFILESAFECALLERWR0(MEDequivalenceCorrespondenceWr,(fid,meshName2,name,dt,it,medtype,medgt,ToMedInt(da2->getNumberOfTuples()),da2->begin()));
516 }
517
518 std::size_t MEDFileEquivalenceCellType::getHeapMemorySizeWithoutChildren() const
519 {
520   return sizeof(MEDFileEquivalenceCellType);
521 }
522
523 MEDFileEquivalenceCellType *MEDFileEquivalenceCellType::deepCopy(MEDFileEquivalencePair *owner) const
524 {
525   MCAuto<DataArrayInt> da;
526   if(getArray())
527     da=getArray()->deepCopy();
528   return new MEDFileEquivalenceCellType(owner,_type,da);
529 }
530
531 bool MEDFileEquivalenceCellType::isEqual(const MEDFileEquivalenceCellType *other, std::string& what) const
532 {
533   if(_type!=other->_type)
534     {
535       what="Geo types differs !";
536       return false;
537     }
538   return MEDFileEquivalenceData::isEqual(other,what);
539 }
540
541 void MEDFileEquivalenceCellType::getRepr(std::ostream& oss) const
542 {
543   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(_type));
544   const DataArrayInt *da(getArray());
545   oss << cm.getRepr() << ":";
546   if(da)
547     oss << da->getNumberOfTuples() << " tuples";
548   else
549     oss << "no dataarray";
550   oss << ",";
551 }
552
553 void MEDFileEquivalenceCellType::writeLL(med_idt fid) const
554 {
555   writeAdvanced(fid,MED_CELL,typmai3[_type]);
556 }
557
558 std::vector<const BigMemoryObject *> MEDFileEquivalenceCell::getDirectChildrenWithNull() const
559 {
560   std::size_t sz(_types.size());
561   std::vector<const BigMemoryObject *> ret(sz);
562   for(std::size_t i=0;i<sz;i++)
563     ret[i]=_types[i];
564   return ret;
565 }
566
567 std::size_t MEDFileEquivalenceCell::getHeapMemorySizeWithoutChildren() const
568 {
569   return sizeof(MEDFileEquivalenceCell)+_types.capacity()*sizeof(MEDFileEquivalenceCellType);
570 }
571
572 MEDFileEquivalenceCell *MEDFileEquivalenceCell::Load(med_idt fid, MEDFileEquivalencePair *owner)
573 {
574   MCAuto<MEDFileEquivalenceCell> ret(new MEDFileEquivalenceCell(owner));
575   ret->load(fid);
576   if(ret->size()>0)
577     return ret.retn();
578   else
579     return 0;
580 }
581
582 void MEDFileEquivalenceCell::writeLL(med_idt fid) const
583 {
584   for(std::vector< MCAuto<MEDFileEquivalenceCellType> >::const_iterator it=_types.begin();it!=_types.end();it++)
585     {
586       const MEDFileEquivalenceCellType *ct(*it);
587       if(ct)
588         ct->writeLL(fid);
589     }
590 }
591
592 MEDFileEquivalenceCell *MEDFileEquivalenceCell::deepCopy(MEDFileEquivalencePair *owner) const
593 {
594   MCAuto<MEDFileEquivalenceCell> ret(new MEDFileEquivalenceCell(owner));
595   for(std::vector< MCAuto<MEDFileEquivalenceCellType> >::const_iterator it=_types.begin();it!=_types.end();it++)
596     {
597       const MEDFileEquivalenceCellType *elt(*it);
598       MCAuto<MEDFileEquivalenceCellType> eltCpy;
599       if(elt)
600         eltCpy=elt->deepCopy(owner);
601       ret->_types.push_back(eltCpy);
602     }
603   return ret.retn();
604 }
605
606 bool MEDFileEquivalenceCell::isEqual(const MEDFileEquivalenceCell *other, std::string& what) const
607 {
608   std::size_t sz(_types.size());
609   if(sz!=other->_types.size())
610     {
611       std::ostringstream oss; oss << "Nb of geo types differs : " << sz << " != " << other->_types.size();
612       what=oss.str();
613       return false;
614     }
615   for(std::size_t i=0;i<sz;i++)
616     {
617       const MEDFileEquivalenceCellType *ct1(_types[i]),*ct2(other->_types[i]);
618       if((ct1 && !ct2) || (!ct1 && ct2))
619         {
620           std::ostringstream oss; oss << "At gt #" << i << " this is defined not other (or reversely !)";
621           what=oss.str();
622           return false;
623         }
624       if(ct1 && ct2)
625         {
626           if(!ct1->isEqual(ct2,what))
627             {
628               std::ostringstream oss; oss << "At gt #" << i << " of Eq " << getFather()->getName() << " it differs !";
629               what=oss.str()+what;
630               return false;
631             }
632         }
633     }
634   return true;
635 }
636
637 void MEDFileEquivalenceCell::getRepr(std::ostream& oss) const
638 {
639   for(std::vector< MCAuto<MEDFileEquivalenceCellType> >::const_iterator it=_types.begin();it!=_types.end();it++)
640     {
641       const MEDFileEquivalenceCellType *elt(*it);
642       if(elt)
643         elt->getRepr(oss);
644     }
645 }
646
647 DataArrayInt *MEDFileEquivalenceCell::getArray(INTERP_KERNEL::NormalizedCellType type)
648 {
649   for(std::vector< MCAuto<MEDFileEquivalenceCellType> >::iterator it=_types.begin();it!=_types.end();it++)
650     {
651       MEDFileEquivalenceCellType *elt(*it);
652       if(elt && elt->getType()==type)
653         return elt->getArray();
654     }
655   std::ostringstream oss; oss << "MEDFileEquivalenceCell::getArray : In Equivalence \"" << getFather()->getName() << "\" the geotype " << type << " is not available !";
656   throw INTERP_KERNEL::Exception(oss.str().c_str());
657 }
658
659 void MEDFileEquivalenceCell::setArray(int meshDimRelToMax, DataArrayInt *da)
660 {
661   if(!da)
662     return ;
663   MEDFileEquivalences::CheckDataArray(da);
664   MEDFileMesh *mm(getMesh());
665   mcIdType totalNbOfCells(mm->getNumberOfCellsAtLevel(meshDimRelToMax));
666   //
667   MCAuto<DataArrayInt> tmp(da->deepCopy()); tmp->rearrange(1);
668   int maxv,minv;
669   tmp->getMinMaxValues(minv,maxv);
670   if((minv<0 || minv>=totalNbOfCells) || (maxv<0 || maxv>=totalNbOfCells))
671     {
672       std::ostringstream oss; oss << "MEDFileEquivalenceCell::setArray : Input 2 component DataArray has incorrect values ! all values must be in [0," << totalNbOfCells << ") !";
673       throw INTERP_KERNEL::Exception(oss.str().c_str());
674     }
675   //
676   std::vector<INTERP_KERNEL::NormalizedCellType> gts(mm->getGeoTypesAtLevel(meshDimRelToMax));
677   int startId(0),endId;
678   std::vector<std::size_t> compS(1,0);
679   for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it=gts.begin();it!=gts.end();it++)
680     {
681       endId=startId+(int)mm->getNumberOfCellsWithType(*it);
682       MCAuto<DataArrayInt> da0(da->keepSelectedComponents(compS));
683       MCAuto<DataArrayIdType> ids(da0->findIdsInRange(startId,endId));
684       MCAuto<DataArrayInt> da1(da->selectByTupleIdSafe(ids->begin(),ids->end()));
685       da1->applyLin(1,-startId);
686       setArrayForType(*it,da1);
687       startId=endId;
688     }
689 }
690
691 void MEDFileEquivalenceCell::setArrayForType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da)
692 {
693   for(std::vector< MCAuto<MEDFileEquivalenceCellType> >::iterator it=_types.begin();it!=_types.end();it++)
694     {
695       MEDFileEquivalenceCellType *elt(*it);
696       if(elt && elt->getType()==type)
697         {
698           elt->setArray(da);
699           return ;
700         }
701     }
702   MCAuto<MEDFileEquivalenceCellType> newElt(new MEDFileEquivalenceCellType(getFather(),type,da));
703   _types.push_back(newElt);
704 }
705
706 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileEquivalenceCell::getTypes() const
707 {
708   std::vector<INTERP_KERNEL::NormalizedCellType> ret;
709   for(std::vector< MCAuto<MEDFileEquivalenceCellType> >::const_iterator it=_types.begin();it!=_types.end();it++)
710     {
711       const MEDFileEquivalenceCellType *elt(*it);
712       if(elt)
713         ret.push_back(elt->getType());
714     }
715   return ret;
716 }
717
718 void MEDFileEquivalenceCell::load(med_idt fid)
719 {
720   std::string meshName(getFather()->getFather()->getMeshName()),name(getName());
721   int dt,it;
722   getFather()->getFather()->getDtIt(dt,it);
723   for(int i=0;i<MED_N_CELL_FIXED_GEO;i++)
724     {
725       med_int ncor;
726       MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceSize,(fid,meshName.c_str(),name.c_str(),dt,it,MED_CELL,typmai[i],&ncor));
727       if(ncor>0)
728         {
729           MCAuto<DataArrayMedInt> da(DataArrayMedInt::New());
730           da->alloc(ncor*2);
731           MEDFILESAFECALLERRD0(MEDequivalenceCorrespondenceRd,(fid,meshName.c_str(),name.c_str(),dt,it,MED_CELL,typmai[i],da->getPointer()));
732           da->applyLin(1,-1);
733           da->rearrange(2);
734           MCAuto<MEDFileEquivalenceCellType> ct(new MEDFileEquivalenceCellType(getFather(),typmai2[i],FromMedIntArray<int>(da)));
735           _types.push_back(ct);
736         }
737     }
738 }
739
740 std::size_t MEDFileEquivalenceNode::getHeapMemorySizeWithoutChildren() const
741 {
742   return sizeof(MEDFileEquivalenceNode);
743 }
744
745 void MEDFileEquivalenceNode::writeLL(med_idt fid) const
746 {
747   writeAdvanced(fid,MED_NODE,MED_NONE);
748 }
749
750 MEDFileEquivalenceNode *MEDFileEquivalenceNode::deepCopy(MEDFileEquivalencePair *owner) const
751 {
752   MCAuto<DataArrayInt> da;
753   if(getArray())
754     da=getArray()->deepCopy();
755   MCAuto<MEDFileEquivalenceNode> ret(new MEDFileEquivalenceNode(owner,da));
756   return ret.retn();
757 }
758
759 bool MEDFileEquivalenceNode::isEqual(const MEDFileEquivalenceNode *other, std::string& what) const
760 {
761   return MEDFileEquivalenceData::isEqual(other,what);
762 }
763
764 void MEDFileEquivalenceNode::getRepr(std::ostream& oss) const
765 {
766   const DataArrayInt *da(getArray());
767   if(!da)
768     oss << " No dataarray defined !" << std::endl;
769   else
770     oss << da->getNumberOfTuples() << " tuples in node equivalence." << std::endl;
771 }