Salome HOME
35b356d0901551a89b8d3108ec213968854ef37f
[tools/medcoupling.git] / src / MEDLoader / MEDFileJoint.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
20 #include "MEDFileJoint.hxx"
21 #include "MEDLoader.hxx"
22 #include "MEDLoaderBase.hxx"
23 #include "MEDFileSafeCaller.txx"
24
25 #include "CellModel.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
32 using namespace MEDCoupling;
33
34 std::size_t MEDFileJointCorrespondence::getHeapMemorySizeWithoutChildren() const
35 {
36   return sizeof(MCAuto<DataArrayInt>);
37 }
38
39 std::vector<const BigMemoryObject *> MEDFileJointCorrespondence::getDirectChildrenWithNull() const
40 {
41   return std::vector<const BigMemoryObject *>();
42 }
43
44 MEDFileJointCorrespondence::MEDFileJointCorrespondence():
45   _is_nodal( true ),
46   _loc_geo_type( INTERP_KERNEL::NORM_ERROR ),
47   _rem_geo_type( INTERP_KERNEL::NORM_ERROR )
48 {
49 }
50
51 /*!
52  * Constructor.
53  *  \param [in] correspondence - correspondence.
54  *  \param [in] is_nodal - is the correspondence of cells or nodes.
55  *  \param [in] loc_geo_type - the local geometry type of correspondence.
56  *  \param [in] rem_geo_type - the remote geometry type of correspondence.
57  */
58 MEDFileJointCorrespondence::MEDFileJointCorrespondence(DataArrayInt* correspondence,
59                                                        bool          isNodal,
60                                                        INTERP_KERNEL::NormalizedCellType loc_geo_type,
61                                                        INTERP_KERNEL::NormalizedCellType rem_geo_type):
62   _is_nodal( isNodal ),
63   _loc_geo_type( loc_geo_type ),
64   _rem_geo_type( rem_geo_type )
65 {
66   MEDFileJointCorrespondence::setCorrespondence( correspondence );
67 }
68
69 MEDFileJointCorrespondence* MEDFileJointCorrespondence::New(DataArrayInt* correspondence,
70                                                             INTERP_KERNEL::NormalizedCellType loc_geo_type,
71                                                             INTERP_KERNEL::NormalizedCellType rem_geo_type)
72 {
73   return new MEDFileJointCorrespondence(correspondence, /*isNodal=*/false, loc_geo_type, rem_geo_type );
74 }
75
76 /*!
77  * Returns a new MEDFileJointCorrespondence of nodes
78  */
79 MEDFileJointCorrespondence *MEDFileJointCorrespondence::New(DataArrayInt* correspondence)
80 {
81   return new MEDFileJointCorrespondence(correspondence);
82 }
83
84 /*!
85  * Returns a new undefined MEDFileJointCorrespondence
86  */
87
88 MEDFileJointCorrespondence *MEDFileJointCorrespondence::New()
89 {
90   return new MEDFileJointCorrespondence();
91 }
92
93 /*!
94  * Writes \a this joint into a MED file specified by its name.
95  *  \param [in] fileName - the MED file name.
96  *  \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
97  *          - 2 - erase; an existing file is removed.
98  *          - 1 - append; same data should not be present in an existing file.
99  *          - 0 - overwrite; same data present in an existing file is overwritten.
100  *  \param [in] order - order.
101  *  \param [in] iteration - iteration.
102  *  \throw If the mesh name is not set.
103  *  \throw If \a mode == 1 and the same data is present in an existing file.
104  */
105 void MEDFileJointCorrespondence::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const
106 {
107   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
108   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
109
110   std::ostringstream oss; oss << "MEDFileJointCorrespondence : error on attempt to write in file : \"" << fileName << "\"";
111   MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
112
113   if (( !_is_nodal ) &&
114       ( _loc_geo_type == INTERP_KERNEL::NORM_ERROR ||
115         _rem_geo_type == INTERP_KERNEL::NORM_ERROR ))
116     {
117       throw INTERP_KERNEL::Exception( "Geometric type not specified for a cell Joint" );
118     }
119
120   if ( (const DataArrayInt *)_correspondence )
121     {
122       writeLL(fid, localMeshName, jointName, order, iteration);
123     }
124   else
125     {
126       throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::write : correspondence array not defined");
127     }
128 }
129
130 void MEDFileJointCorrespondence::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const
131 {
132   if ( _is_nodal )
133     {
134       MEDFILESAFECALLERWR0(MEDsubdomainCorrespondenceWr,(fid, localMeshName.c_str(), jointName.c_str(),
135                                                          order, iteration,
136                                                          MED_NODE, MED_NONE,
137                                                          MED_NODE, MED_NONE,
138                                                          _correspondence->getNbOfElems()/2,
139                                                          _correspondence->getConstPointer()));
140     }
141   else
142     {
143       MEDFILESAFECALLERWR0(MEDsubdomainCorrespondenceWr,(fid, localMeshName.c_str(), jointName.c_str(),
144                                                          order, iteration,
145                                                          MED_CELL, typmai3[ _loc_geo_type ],
146                                                          MED_CELL, typmai3[ _rem_geo_type ],
147                                                          _correspondence->getNbOfElems()/2,
148                                                          _correspondence->getConstPointer()));
149     }
150 }
151
152 void MEDFileJointCorrespondence::setCorrespondence(DataArrayInt *corr)
153 {
154   _correspondence=corr;
155   if ( corr )
156     corr->incrRef();
157 }
158
159 /*!
160  * Checks if \a this and another mesh are equal.
161  *  \param [in] other - the mesh to compare with.
162  *  \return bool - \c true if the meshes are equal, \c false, else.
163  */
164 bool MEDFileJointCorrespondence::isEqual(const MEDFileJointCorrespondence *other) const
165 {
166   if(_is_nodal!=other->_is_nodal)
167     return false;
168   if(_loc_geo_type!=other->_loc_geo_type)
169     return false;
170   if(_rem_geo_type!=other->_rem_geo_type)
171     return false;
172   if(!_correspondence->isEqual(*other->_correspondence))
173     return false;
174   return true;
175 }
176
177 MEDFileJointCorrespondence *MEDFileJointCorrespondence::deepCopy() const
178 {
179   MCAuto<MEDFileJointCorrespondence> ret=new MEDFileJointCorrespondence(*this);
180   return ret.retn();
181 }
182
183 MEDFileJointCorrespondence *MEDFileJointCorrespondence::shallowCpy() const
184 {
185   MCAuto<MEDFileJointCorrespondence> ret=new MEDFileJointCorrespondence(*this);
186   return ret.retn();
187 }
188
189 /*!
190  * Returns a string describing \a this mesh. This description includes the correspondence and
191  * the number correspondence.
192  *  \return std::string - the joint information string.
193  */
194 std::string MEDFileJointCorrespondence::simpleRepr() const
195 {
196   std::ostringstream oss;
197   oss << "(*************************************)\n(* JOINT_CORRESPOND INFORMATION: *)\n(*************************************)\n";
198   oss << "- entity type of the correspondence : " << ( getIsNodal() ? "NODE" : "CELL" ) << "\n";
199   oss << "- Local geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _loc_geo_type ).getRepr() << "\n";
200   oss << "- Remote geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _rem_geo_type ).getRepr() << "\n";
201   if ( (const DataArrayInt *)_correspondence )
202     {
203       oss << "- Number entity of the correspondence : " << getCorrespondence()->getNumberOfTuples() << "\n";
204
205       const DataArrayInt* tmp=getCorrespondence();
206       oss << "- Correspondence : <<";
207       for(const int *it=tmp->begin();it!=tmp->end();it++)
208         oss<< *it << " ";
209     }
210   else
211     {
212       oss << "- Number entity of the correspondence : 0\n";
213     }
214   oss << std::endl;
215   return oss.str();
216 }
217
218
219 MEDFileJointOneStep::MEDFileJointOneStep():_order(-1),_iteration(-1)
220 {
221 }
222
223 std::size_t MEDFileJointOneStep::getHeapMemorySizeWithoutChildren() const
224 {
225   return _correspondences.capacity()*sizeof(MCAuto<DataArrayInt>);
226 }
227
228 std::vector<const BigMemoryObject *> MEDFileJointOneStep::getDirectChildrenWithNull() const
229 {
230   return std::vector<const BigMemoryObject *>();
231 }
232
233 MEDFileJointOneStep *MEDFileJointOneStep::New(int dt, int it)
234 {
235   MEDFileJointOneStep* j = new MEDFileJointOneStep();
236   j->setOrder( dt );
237   j->setIteration( it );
238   return j;
239 }
240
241 /*!
242  * Returns a new MEDFileJointOneStep.
243  *  \param [in] fileName - the name of MED file to read.
244  *  \param [in] mName - the name of the mesh to read.
245  *  \param [in] jointName - the joint name.
246  *  \param [in] num - the number of an iteration.
247  *  \return MEDFileMesh * - a new instance of MEDFileJointOneStep.
248  *  \throw If the file is not readable.
249  *  \throw If there is no mesh with given attributes in the file.
250  */
251 MEDFileJointOneStep *MEDFileJointOneStep::New(const std::string& fileName, const std::string& mName, const std::string& jointName, int num)
252 {
253   MEDFileUtilities::CheckFileForRead(fileName);
254   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY);
255   return new MEDFileJointOneStep(fid, mName, jointName, num);
256 }
257
258 MEDFileJointOneStep* MEDFileJointOneStep::New(med_idt fid, const std::string& mName, const std::string& jointName, int num)
259 {
260   return new MEDFileJointOneStep( fid, mName, jointName, num);
261 }
262
263 MEDFileJointOneStep::MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int num)
264 {
265   int order, iteration, ncorrespondence;
266   MEDFILESAFECALLERRD0(MEDsubdomainComputingStepInfo,(fid, mName.c_str(), jointName.c_str(), num, &order, &iteration, &ncorrespondence));
267   MEDFileJointOneStep::setOrder(order);
268   MEDFileJointOneStep::setIteration(iteration);
269   for ( int cur_it = 1; cur_it <= ncorrespondence; ++cur_it )
270     {
271       int num_entity;
272       med_entity_type loc_ent_type, rem_ent_type;
273       med_geometry_type loc_geo_type, rem_geo_type;
274       MEDFILESAFECALLERRD0(MEDsubdomainCorrespondenceSizeInfo,(fid, mName.c_str(), jointName.c_str(), order, iteration, cur_it,
275                                                                &loc_ent_type, &loc_geo_type, &rem_ent_type, &rem_geo_type, &num_entity));
276       if ( num_entity > 0 )
277         {
278           MCAuto<DataArrayInt> correspondence=DataArrayInt::New();
279           correspondence->alloc(num_entity*2, 1);
280           MEDFILESAFECALLERRD0(MEDsubdomainCorrespondenceRd,(fid, mName.c_str(), jointName.c_str(), order, iteration, loc_ent_type,
281                                                              loc_geo_type, rem_ent_type, rem_geo_type, correspondence->getPointer()));
282           MEDFileJointCorrespondence *cor=MEDFileJointCorrespondence::New();
283           cor->setIsNodal( loc_ent_type == MED_NODE );
284           cor->setLocalGeometryType ( convertGeometryType( loc_geo_type ));
285           cor->setRemoteGeometryType( convertGeometryType( rem_geo_type ));
286           cor->setCorrespondence( correspondence );
287           _correspondences.push_back(cor);
288         }
289     }
290 }
291
292 /*!
293  * Writes \a this joint into a MED file specified by its name.
294  *  \param [in] fileName - the MED file name.
295  *  \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
296  * - 2 - erase; an existing file is removed.
297  * - 1 - append; same data should not be present in an existing file.
298  * - 0 - overwrite; same data present in an existing file is overwritten.
299  *  \throw If the mesh name is not set.
300  *  \throw If \a mode == 1 and the same data is present in an existing file.
301  */
302 void MEDFileJointOneStep::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const
303 {
304   med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
305   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
306   std::ostringstream oss; oss << "MEDFileJointOneStep : error on attempt to write in file : \"" << fileName << "\"";
307   MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
308   if ( _correspondences.empty() )
309     throw INTERP_KERNEL::Exception("MEDFileJointOneStep::write : no correspondences defined !");
310   writeLL(fid, localMeshName, jointName);
311 }
312
313 void MEDFileJointOneStep::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const
314 {
315   for(std::vector< MCAuto<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++)
316     {
317       (*it)->writeLL(fid, localMeshName, jointName, getOrder(), getIteration());
318     }
319 }
320
321 void MEDFileJointOneStep::pushCorrespondence(MEDFileJointCorrespondence* correspondence)
322 {
323   if(!correspondence)
324     throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::pushCorrespondence : invalid input pointer ! should be different from 0 !");
325   _correspondences.push_back(correspondence);
326   correspondence->incrRef();
327 }
328
329 int MEDFileJointOneStep::getNumberOfCorrespondences() const
330 {
331   return _correspondences.size();
332 }
333
334 /** Return a borrowed reference (caller is not responsible) */
335 MEDFileJointCorrespondence *MEDFileJointOneStep::getCorrespondenceAtPos(int i) const
336 {
337   if(i<0 || i>=(int)_correspondences.size())
338     {
339       std::ostringstream oss; oss << "MEDFileJointOneStep::getCorrespondenceAtPos : invalid correspondence id given in parameter ! Should be in [0;" << _correspondences.size() << ") !";
340       throw INTERP_KERNEL::Exception(oss.str().c_str());
341     }
342   const MEDFileJointCorrespondence* ret = _correspondences[i];
343   return const_cast<MEDFileJointCorrespondence *>( ret );
344 }
345
346 /*!
347  * Checks if \a this and another Joint are equal.
348  *  \param [in] other - the Joint to compare with.
349  *  \return bool - \c true if the Joints are equal, \c false, else.
350  */
351 bool MEDFileJointOneStep::isEqual(const MEDFileJointOneStep *other) const
352 {
353   if(_order!=other->_order)
354     return false;
355   if(_iteration!=other->_iteration)
356     return false;
357   if ( getNumberOfCorrespondences() != other->getNumberOfCorrespondences() )
358     return false;
359
360   std::vector<bool> found( getNumberOfCorrespondences(), false );
361   for(int i=0; i<getNumberOfCorrespondences(); i++)
362     {
363       int j;
364       for(j=0; j<getNumberOfCorrespondences(); j++)
365         {
366           if ( !found[ j ] &&
367                getCorrespondenceAtPos(i)->isEqual(other->getCorrespondenceAtPos(j)))
368             {
369               found[ j ] = true;
370               break;
371             }
372         }
373       if ( j == getNumberOfCorrespondences() )
374         return false;
375     }
376   return true;
377 }
378
379 MEDFileJointOneStep *MEDFileJointOneStep::deepCopy() const
380 {
381   std::vector< MCAuto<MEDFileJointCorrespondence> > correspondences(_correspondences.size());
382   std::size_t i=0;
383   for(std::vector< MCAuto<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++,i++)
384     if((const MEDFileJointCorrespondence *)*it)
385       correspondences[i]=(*it)->deepCopy();
386   MCAuto<MEDFileJointOneStep> ret= new MEDFileJointOneStep;
387   ret->_correspondences=correspondences;
388   return ret.retn();
389 }
390
391 MEDFileJointOneStep *MEDFileJointOneStep::shallowCpy() const
392 {
393   MCAuto<MEDFileJointOneStep> ret=new MEDFileJointOneStep(*this);
394   return ret.retn();
395 }
396
397 /*!
398  * Returns a string describing \a this Joint. This description includes the correspondence and
399  * the number of correspondences.
400  *  \return std::string - the joint information string.
401  */
402 std::string MEDFileJointOneStep::simpleRepr() const
403 {
404   std::ostringstream oss;
405   oss << "(*************************************)\n(* JOINT_ONE_STEP INFORMATION: *)\n(*************************************)\n";
406   oss << "- Number of the correspondences : <<" << _correspondences.size() << ">>\n";
407   for(std::vector< MCAuto<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++)
408     {
409       oss << (*it)->simpleRepr();
410     }
411   return oss.str();
412 }
413
414 INTERP_KERNEL::NormalizedCellType MEDFileJointOneStep::convertGeometryType(med_geometry_type geotype)
415 {
416   INTERP_KERNEL::NormalizedCellType result=INTERP_KERNEL::NORM_ERROR;
417   for(int i=0; i<MED_N_CELL_FIXED_GEO; i++)
418     {
419       if (typmai[i]==geotype)
420         {
421           result=typmai2[i];
422           break;
423         }
424     }
425   return result;
426 }
427
428 std::size_t MEDFileJoint::getHeapMemorySizeWithoutChildren() const
429 {
430   return _joint.capacity()*sizeof(MCAuto<MEDFileJointOneStep>);
431 }
432
433 std::vector<const BigMemoryObject *> MEDFileJoint::getDirectChildrenWithNull() const
434 {
435   return std::vector<const BigMemoryObject *>();
436 }
437
438 MEDFileJoint *MEDFileJoint::New()
439 {
440   return new MEDFileJoint();
441 }
442
443 MEDFileJoint *MEDFileJoint::New(const std::string& fileName, const std::string& mName, int curJoint)
444 {
445   MEDFileUtilities::CheckFileForRead(fileName);
446   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY);
447   return new MEDFileJoint(fid,mName,curJoint);
448 }
449
450 MEDFileJoint *MEDFileJoint::New(med_idt fid, const std::string& mName, int curJoint)
451 {
452   return new MEDFileJoint(fid,mName,curJoint);
453 }
454
455 MEDFileJoint *MEDFileJoint::New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum)
456 {
457   MEDFileJoint* j = new MEDFileJoint();
458   j->setJointName( jointName );
459   j->setLocalMeshName( locMeshName );
460   j->setRemoteMeshName( remoteMeshName );
461   j->setDomainNumber( remoteMeshNum );
462   return j;
463 }
464
465 MEDFileJoint::MEDFileJoint()
466 {
467 }
468
469 /*!
470  * Returns a new MEDFileJoint holding the mesh data that has been read from a given MED
471  * file. The Joint to load is specified by mesh name and a Joint iteration.
472  *  \param [in] fileName - the name of MED file to read.
473  *  \param [in] mName - the name of the mesh to read.
474  *  \param [in] curJoint - the iteration number of current joint.
475  *  \return MEDFileJoint * - a new instance of MEDFileJoint.
476  *  \throw If the file is not readable.
477  *  \throw If there is no mesh with given attributes in the file.
478  */
479 MEDFileJoint::MEDFileJoint(med_idt fid, const std::string& mName, int curJoint)
480 {
481   INTERP_KERNEL::AutoPtr<char> joint_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
482   INTERP_KERNEL::AutoPtr<char> desc_name=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
483   INTERP_KERNEL::AutoPtr<char> rem_mesh_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
484   int domain_number=0, nstep=0, nocstpncorrespondence=0;
485   MEDFILESAFECALLERRD0(MEDsubdomainJointInfo,(fid,mName.c_str(), curJoint, joint_name, desc_name, &domain_number,rem_mesh_name,
486                                               &nstep, &nocstpncorrespondence));
487   setLocalMeshName(mName);
488   setRemoteMeshName(MEDLoaderBase::buildStringFromFortran(rem_mesh_name,MED_NAME_SIZE));
489   setDescription(MEDLoaderBase::buildStringFromFortran(desc_name,MED_COMMENT_SIZE));
490   setJointName(MEDLoaderBase::buildStringFromFortran(joint_name,MED_NAME_SIZE));
491   setDomainNumber(domain_number);
492   for(int cur_step=1; cur_step <= nstep; ++cur_step)
493     {
494       MEDFileJointOneStep *cor=MEDFileJointOneStep::New(fid, mName.c_str(), getJointName(), cur_step);
495       _joint.push_back(cor);
496     }
497 }
498
499 void MEDFileJoint::writeLL(med_idt fid) const
500 {
501   // if ( _loc_mesh_name.empty() )
502   //   throw INTERP_KERNEL::Exception("MEDFileJoint::write : name of a local mesh not defined!");
503   MEDFILESAFECALLERWR0(MEDsubdomainJointCr,(fid,getLocalMeshName().c_str(),getJointName().c_str(),getDescription().c_str(),getDomainNumber(),getRemoteMeshName().c_str()));
504   for(std::vector< MCAuto<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++)
505     (*it)->writeLL(fid, getLocalMeshName(),getJointName());
506 }
507
508 void MEDFileJoint::pushStep(MEDFileJointOneStep* step)
509 {
510   if(!step)
511     throw INTERP_KERNEL::Exception("MEDFileJoint::pushStep : invalid input pointer ! should be different from 0 !");
512   _joint.push_back(step);
513   step->incrRef();
514 }
515
516 int MEDFileJoint::getNumberOfSteps() const
517 {
518   return _joint.size();
519 }
520
521 /** Return a borrowed reference (caller is not responsible) */
522 MEDFileJointOneStep *MEDFileJoint::getStepAtPos(int i) const
523 {
524   if(i<0 || i>=(int)_joint.size())
525     {
526       std::ostringstream oss; oss << "MEDFileJoint::getStepAtPos : invalid step id given in parameter ! Should be in [0;" << _joint.size() << ") !";
527       throw INTERP_KERNEL::Exception(oss.str().c_str());
528     }
529   const MEDFileJointOneStep* ret = _joint[i];
530   return const_cast<MEDFileJointOneStep *>( ret );
531 }
532
533 /*!
534  * Checks if \a this and another Joint are equal.
535  *  \param [in] other - the Joint to compare with.
536  *  \return bool - \c true if the Joints are equal, \c false, else.
537  */
538 bool MEDFileJoint::isEqual(const MEDFileJoint *other) const
539 {
540   if(_loc_mesh_name!=other->_loc_mesh_name)
541     return false;
542   if(_joint_name!=other->_joint_name)
543     return false;
544   if(_desc_name!=other->_desc_name)
545       return false;
546   if(_rem_mesh_name!=other->_rem_mesh_name)
547     return false;
548   if(_domain_number!=other->_domain_number)
549     return false;
550   int nbTS(getNumberOfSteps());
551   if(nbTS!=other->getNumberOfSteps())
552     return false;
553   std::vector<bool> found(nbTS,false);
554   for(int i=0;i<nbTS;i++)
555     {
556       int j;
557       for(j=0;j<nbTS;j++)
558         {
559           if(!found[j] && getStepAtPos(i)->isEqual(other->getStepAtPos(j)))
560             {
561               found[j]=true;
562               break;
563             }
564         }
565       if(j==nbTS)
566         return false;
567     }
568   return true;
569 }
570
571 MEDFileJoint *MEDFileJoint::deepCopy() const
572 {
573   std::vector< MCAuto<MEDFileJointOneStep> > joint(_joint.size());
574   std::size_t i=0;
575   for(std::vector< MCAuto<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++,i++)
576     if((const MEDFileJointOneStep *)*it)
577       joint[i]=(*it)->deepCopy();
578   MCAuto<MEDFileJoint> ret=MEDFileJoint::New();
579   ret->_joint=joint;
580   return ret.retn();
581 }
582
583 MEDFileJoint *MEDFileJoint::shallowCpy() const
584 {
585   MCAuto<MEDFileJoint> ret=new MEDFileJoint(*this);
586   return ret.retn();
587 }
588
589 bool MEDFileJoint::changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
590 {
591   for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
592     {
593       if((*it).first==_joint_name)
594         {
595           _joint_name=(*it).second;
596           return true;
597         }
598     }
599   return false;
600 }
601
602 /*!
603  * Returns a string describing \a this mesh. This description includes the correspondence and
604  * the number correspondence.
605  *  \return std::string - the joint information string.
606  */
607 std::string MEDFileJoint::simpleRepr() const
608 {
609   std::ostringstream oss;
610   oss << "(*************************************)\n(* JOINT INFORMATION: *)\n(*************************************)\n";
611   oss << "- Local Mesh name : <<" << getLocalMeshName() << ">>\n";
612   oss << "- Remote Mesh name : <<" << getRemoteMeshName() << ">>\n";
613   oss << "- Description : <<" << getDescription() << ">>\n";
614   oss << "- Joint name : <<" << getJointName() << ">>\n";
615   oss << "- Domain number : " << getDomainNumber() << "\n";
616   for(std::vector< MCAuto<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++)
617     {
618       oss << (*it)->simpleRepr();
619     }
620   return oss.str();
621 }
622
623 MEDFileJoints *MEDFileJoints::New()
624 {
625   return new MEDFileJoints;
626 }
627
628 MEDFileJoints *MEDFileJoints::New(const std::string& fileName, const std::string& meshName)
629 {
630   MEDFileUtilities::CheckFileForRead(fileName);
631   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY);
632   return new MEDFileJoints( fid, meshName );
633 }
634
635 MEDFileJoints *MEDFileJoints::New(med_idt fid, const std::string& meshName)
636 {
637   return new MEDFileJoints( fid, meshName );
638 }
639
640 void MEDFileJoints::writeLL(med_idt fid) const
641 {
642   for(std::vector< MCAuto<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++)
643     (*it)->writeLL(fid);
644 }
645
646 std::string MEDFileJoints::getMeshName() const
647 {
648   for ( size_t i = 0; i <= _joints.size(); ++i )
649     if ( (const MEDFileJoint*) _joints[i] )
650       return _joints[i]->getLocalMeshName();
651
652   return "";
653 }
654
655 int MEDFileJoints::getNumberOfJoints() const
656 {
657   return _joints.size();
658 }
659
660 /** Return a borrowed reference (caller is not responsible) */
661 MEDFileJoint *MEDFileJoints::getJointAtPos(int i) const
662 {
663   if(i<0 || i>=(int)_joints.size())
664     {
665       std::ostringstream oss; oss << "MEDFileJoints::getJointAtPos : invalid joint id given in parameter ! Should be in [0;" << _joints.size() << ") !";
666       throw INTERP_KERNEL::Exception(oss.str().c_str());
667     }
668   const MEDFileJoint* ret = _joints[i];
669   return const_cast<MEDFileJoint *>( ret );
670 }
671
672
673 /** Return a borrowed reference (caller is not responsible) */
674 MEDFileJoint *MEDFileJoints::getJointWithName(const std::string& jname) const
675 {
676   std::vector<std::string> js=getJointsNames();
677   std::vector<std::string>::iterator it=std::find(js.begin(),js.end(),jname);
678   if(it==js.end())
679     {
680       std::ostringstream oss; oss << "MEDFileJoints::getJointWithName : Joint  \"" << jname << "\" does not exist in this ! Existing are : ";
681       std::copy(js.begin(),js.end(),std::ostream_iterator<std::string>(oss," "));
682       throw INTERP_KERNEL::Exception(oss.str().c_str());
683     }
684   return getJointAtPos((int)std::distance(js.begin(),it));
685 }
686
687 std::vector<std::string> MEDFileJoints::getJointsNames() const
688 {
689   std::vector<std::string> ret(_joints.size());
690   int i=0;
691   for(std::vector< MCAuto<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++)
692     {
693       const MEDFileJoint *f=(*it);
694       if(f)
695         {
696           ret[i]=f->getJointName();
697         }
698       else
699         {
700           std::ostringstream oss; oss << "MEDFileJoints::getJointsNames : At rank #" << i << " joint is not defined !";
701           throw INTERP_KERNEL::Exception(oss.str().c_str());
702         }
703     }
704   return ret;
705 }
706
707 bool MEDFileJoints::changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
708 {
709   bool ret=false;
710   for(std::vector< MCAuto<MEDFileJoint> >::iterator it=_joints.begin();it!=_joints.end();it++)
711     {
712       MEDFileJoint *cur(*it);
713       if(cur)
714         ret=cur->changeJointNames(modifTab) || ret;
715     }
716   return ret;
717 }
718
719 void MEDFileJoints::resize(int newSize)
720 {
721   _joints.resize(newSize);
722 }
723
724 void MEDFileJoints::pushJoint(MEDFileJoint *joint)
725 {
726   if(!joint)
727     throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : invalid input pointer ! should be different from 0 !");
728   if ( !_joints.empty() &&
729        _joints[0]->getLocalMeshName() != joint->getLocalMeshName() )
730     throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : different names of local meshes ! should be equal !");
731
732   _joints.push_back(joint);
733   joint->incrRef();
734 }
735
736 void MEDFileJoints::setJointAtPos(int i, MEDFileJoint *joint)
737 {
738   if(!joint)
739     throw INTERP_KERNEL::Exception("MEDFileJoints::setJointAtPos : invalid input pointer ! should be different from 0 !");
740   if(i>=(int)_joints.size())
741     _joints.resize(i+1);
742   _joints[i]=joint;
743   joint->incrRef();
744 }
745
746 void MEDFileJoints::destroyJointAtPos(int i)
747 {
748   if(i<0 || i>=(int)_joints.size())
749     {
750       std::ostringstream oss; oss << "MEDFileJoints::destroyJointAtPos : Invalid given id in input (" << i << ") should be in [0," << _joints.size() << ") !";
751       throw INTERP_KERNEL::Exception(oss.str().c_str());
752     }
753   _joints.erase(_joints.begin()+i);
754 }
755
756 MEDFileJoints::MEDFileJoints()
757 {
758 }
759
760 MEDFileJoints::MEDFileJoints(med_idt fid, const std::string& meshName)
761 {
762   int num_joint=MEDnSubdomainJoint(fid, meshName.c_str() );
763   for(int i = 1; i <= num_joint; i++)
764     _joints.push_back(MEDFileJoint::New(fid,meshName,i));
765 }
766
767 MEDFileJoints *MEDFileJoints::deepCopy() const
768 {
769   std::vector< MCAuto<MEDFileJoint> > joints(_joints.size());
770   std::size_t i=0;
771   for(std::vector< MCAuto<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++)
772     if((const MEDFileJoint *)*it)
773       joints[i]=(*it)->deepCopy();
774   MCAuto<MEDFileJoints> ret=MEDFileJoints::New();
775   ret->_joints=joints;
776   return ret.retn();
777 }
778
779 std::size_t MEDFileJoints::getHeapMemorySizeWithoutChildren() const
780 {
781   return _joints.capacity()*(sizeof(MCAuto<MEDFileJoint>));
782 }
783
784 std::vector<const BigMemoryObject *> MEDFileJoints::getDirectChildrenWithNull() const
785 {
786   std::vector<const BigMemoryObject *> ret;
787   for(std::vector< MCAuto<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++)
788     ret.push_back((const MEDFileJoint *)*it);
789   return ret;
790 }
791
792 std::string MEDFileJoints::simpleRepr() const
793 {
794   std::ostringstream oss;
795   oss << "(*****************)\n(* MEDFileJoints *)\n(*****************)\n\n";
796   simpleReprWithoutHeader(oss);
797   return oss.str();
798 }
799
800 void MEDFileJoints::simpleReprWithoutHeader(std::ostream& oss) const
801 {
802   int nbOfJoints=getNumberOfJoints();
803   oss << "There are " << nbOfJoints << " joints with the following names : \n";
804   std::vector<std::string> jns=getJointsNames();
805   for(int i=0;i<nbOfJoints;i++)
806     oss << "  - #" << i << " \"" << jns[i] << "\"\n";
807   for(std::vector< MCAuto<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++)
808     {
809       oss << (*it)->simpleRepr();
810     }
811 }