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