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