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