1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileUtilities.hxx"
23 #include "MEDFileFieldOverView.hxx"
24 #include "MEDFileField.hxx"
25 #include "MEDLoader.hxx"
26 #include "MEDFileSafeCaller.txx"
27 #include "MEDLoaderBase.hxx"
29 #include "MEDCouplingUMesh.hxx"
31 #include "InterpKernelAutoPtr.hxx"
36 extern med_geometry_type typmai3[34];
38 using namespace ParaMEDMEM;
40 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
42 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
46 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
48 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
49 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
51 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
52 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
53 ret+=(*it2).capacity();
55 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
56 ret+=(*it).first.capacity()+sizeof(int);
60 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
62 std::vector<const BigMemoryObject *> ret(1);
63 ret[0]=(const MEDFileEquivalences *)_equiv;
68 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
69 * file. The first mesh in the file is loaded.
70 * \param [in] fileName - the name of MED file to read.
71 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
72 * mesh using decrRef() as it is no more needed.
73 * \throw If the file is not readable.
74 * \throw If there is no meshes in the file.
75 * \throw If the mesh in the file is of a not supported type.
77 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
79 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
82 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
83 throw INTERP_KERNEL::Exception(oss.str().c_str());
85 MEDFileUtilities::CheckFileForRead(fileName);
86 ParaMEDMEM::MEDCouplingMeshType meshType;
87 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
90 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
91 MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ret;
96 ret=MEDFileUMesh::New();
101 ret=MEDFileCMesh::New();
106 ret=MEDFileCurveLinearMesh::New();
111 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
112 throw INTERP_KERNEL::Exception(oss.str().c_str());
115 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
120 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
121 * file. The mesh to load is specified by its name and numbers of a time step and an
123 * \param [in] fileName - the name of MED file to read.
124 * \param [in] mName - the name of the mesh to read.
125 * \param [in] dt - the number of a time step.
126 * \param [in] it - the number of an iteration.
127 * \param [in] joints - the sub-domain joints to use instead of those that can be read
128 * from the MED file. Usually this joints are those just read by another iteration
129 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
130 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
131 * mesh using decrRef() as it is no more needed.
132 * \throw If the file is not readable.
133 * \throw If there is no mesh with given attributes in the file.
134 * \throw If the mesh in the file is of a not supported type.
136 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
138 MEDFileUtilities::CheckFileForRead(fileName);
139 ParaMEDMEM::MEDCouplingMeshType meshType;
140 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
143 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
144 MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ret;
149 ret=MEDFileUMesh::New();
154 ret=MEDFileCMesh::New();
159 ret=MEDFileCurveLinearMesh::New();
164 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
165 throw INTERP_KERNEL::Exception(oss.str().c_str());
168 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
173 * Writes \a this mesh into an open MED file specified by its descriptor.
174 * \param [in] fid - the MED file descriptor.
175 * \throw If the mesh name is not set.
176 * \throw If the file is open for reading only.
177 * \throw If the writing mode == 1 and the same data is present in an existing file.
179 void MEDFileMesh::write(med_idt fid) const
182 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
184 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
187 const MEDFileEquivalences *eqs(_equiv);
193 * Writes \a this mesh into a MED file specified by its name.
194 * \param [in] fileName - the MED file name.
195 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
196 * - 2 - erase; an existing file is removed.
197 * - 1 - append; same data should not be present in an existing file.
198 * - 0 - overwrite; same data present in an existing file is overwritten.
199 * \throw If the mesh name is not set.
200 * \throw If \a mode == 1 and the same data is present in an existing file.
202 void MEDFileMesh::write(const std::string& fileName, int mode) const
204 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
205 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
206 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
207 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
212 * Checks if \a this and another mesh are equal.
213 * \param [in] other - the mesh to compare with.
214 * \param [in] eps - a precision used to compare real values.
215 * \param [in,out] what - the string returning description of unequal data.
216 * \return bool - \c true if the meshes are equal, \c false, else.
218 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
220 if(_order!=other->_order)
222 what="Orders differ !";
225 if(_iteration!=other->_iteration)
227 what="Iterations differ !";
230 if(fabs(_time-other->_time)>eps)
232 what="Time values differ !";
235 if(_dt_unit!=other->_dt_unit)
237 what="Time units differ !";
240 if(_name!=other->_name)
242 what="Names differ !";
245 //univ_name has been ignored -> not a bug because it is a mutable attribute
246 if(_desc_name!=other->_desc_name)
248 what="Description names differ !";
251 if(!areGrpsEqual(other,what))
253 if(!areFamsEqual(other,what))
255 if(!areEquivalencesEqual(other,what))
260 void MEDFileMesh::setName(const std::string& name)
266 * Clears redundant attributes of incorporated data arrays.
268 void MEDFileMesh::clearNonDiscrAttributes() const
273 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
275 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
277 if((*it).first==_name)
287 * Copies data on groups and families from another mesh.
288 * \param [in] other - the mesh to copy the data from.
290 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
292 _groups=other._groups;
293 _families=other._families;
298 * This method clear all the groups in the map.
299 * So this method does not operate at all on arrays.
300 * So this method can lead to orphan families.
302 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
304 void MEDFileMesh::clearGrpMap()
310 * This method clear all the families in the map.
311 * So this method does not operate at all on arrays.
312 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
314 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
316 void MEDFileMesh::clearFamMap()
322 * This method clear all the families and groups in the map.
323 * So this method does not operate at all on arrays.
324 * As all groups and families entry will be removed after
325 * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object.
327 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
329 void MEDFileMesh::clearFamGrpMaps()
336 * Returns names of families constituting a group.
337 * \param [in] name - the name of the group of interest.
338 * \return std::vector<std::string> - a sequence of names of the families.
339 * \throw If the name of a nonexistent group is specified.
341 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
343 std::string oname(name);
344 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
345 if(it==_groups.end())
347 std::vector<std::string> grps=getGroupsNames();
348 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
349 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
350 throw INTERP_KERNEL::Exception(oss.str().c_str());
356 * Returns names of families constituting some groups.
357 * \param [in] grps - a sequence of names of groups of interest.
358 * \return std::vector<std::string> - a sequence of names of the families.
359 * \throw If a name of a nonexistent group is present in \a grps.
361 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
363 std::set<std::string> fams;
364 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
366 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
367 if(it2==_groups.end())
369 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
370 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
371 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
372 throw INTERP_KERNEL::Exception(oss.str().c_str());
374 fams.insert((*it2).second.begin(),(*it2).second.end());
376 std::vector<std::string> fams2(fams.begin(),fams.end());
381 * Returns ids of families constituting a group.
382 * \param [in] name - the name of the group of interest.
383 * \return std::vector<int> - sequence of ids of the families.
384 * \throw If the name of a nonexistent group is specified.
386 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
388 std::string oname(name);
389 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
390 std::vector<std::string> grps=getGroupsNames();
391 if(it==_groups.end())
393 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
394 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
395 throw INTERP_KERNEL::Exception(oss.str().c_str());
397 return getFamiliesIds((*it).second);
401 * Sets names of families constituting a group. If data on families of this group is
402 * already present, it is overwritten. Every family in \a fams is checked, and if a
403 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
404 * \param [in] name - the name of the group of interest.
405 * \param [in] fams - a sequence of names of families constituting the group.
407 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
409 std::string oname(name);
411 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
413 std::map<std::string,int>::iterator it2=_families.find(*it1);
414 if(it2==_families.end())
420 * Sets families constituting a group. The families are specified by their ids.
421 * If a family name is not found by its id, an exception is thrown.
422 * If several families have same id, the first one in lexical order is taken.
423 * \param [in] name - the name of the group of interest.
424 * \param [in] famIds - a sequence of ids of families constituting the group.
425 * \throw If a family name is not found by its id.
427 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
429 std::string oname(name);
430 std::vector<std::string> fams(famIds.size());
432 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
434 std::string name2=getFamilyNameGivenId(*it1);
441 * Returns names of groups including a given family.
442 * \param [in] name - the name of the family of interest.
443 * \return std::vector<std::string> - a sequence of names of groups including the family.
445 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
447 std::vector<std::string> ret;
448 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
450 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
453 ret.push_back((*it1).first);
461 * Adds an existing family to groups.
462 * \param [in] famName - a name of family to add to \a grps.
463 * \param [in] grps - a sequence of group names to add the family in.
464 * \throw If a family named \a famName not yet exists.
466 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
468 std::string fName(famName);
469 const std::map<std::string,int>::const_iterator it=_families.find(fName);
470 if(it==_families.end())
472 std::vector<std::string> fams=getFamiliesNames();
473 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
474 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
475 throw INTERP_KERNEL::Exception(oss.str().c_str());
477 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
479 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
480 if(it2!=_groups.end())
481 (*it2).second.push_back(fName);
484 std::vector<std::string> grps2(1,fName);
491 * Returns names of all groups of \a this mesh.
492 * \return std::vector<std::string> - a sequence of group names.
494 std::vector<std::string> MEDFileMesh::getGroupsNames() const
496 std::vector<std::string> ret(_groups.size());
498 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
504 * Returns names of all families of \a this mesh.
505 * \return std::vector<std::string> - a sequence of family names.
507 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
509 std::vector<std::string> ret(_families.size());
511 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
517 * Changes a name of every family, included in one group only, to be same as the group name.
518 * \throw If there are families with equal names in \a this mesh.
520 void MEDFileMesh::assignFamilyNameWithGroupName()
522 std::map<std::string, std::vector<std::string> > groups(_groups);
523 std::map<std::string,int> newFams;
524 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
526 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
527 if(grps.size()==1 && groups[grps[0]].size()==1)
529 if(newFams.find(grps[0])!=newFams.end())
531 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
532 throw INTERP_KERNEL::Exception(oss.str().c_str());
534 newFams[grps[0]]=(*it).second;
535 std::vector<std::string>& grps2=groups[grps[0]];
536 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
541 if(newFams.find((*it).first)!=newFams.end())
543 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
544 throw INTERP_KERNEL::Exception(oss.str().c_str());
546 newFams[(*it).first]=(*it).second;
554 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
556 * \return the removed groups.
558 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
560 std::vector<std::string> ret;
561 std::map<std::string, std::vector<std::string> > newGrps;
562 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
564 if((*it).second.empty())
565 ret.push_back((*it).first);
567 newGrps[(*it).first]=(*it).second;
575 * Removes a group from \a this mesh.
576 * \param [in] name - the name of the group to remove.
577 * \throw If no group with such a \a name exists.
579 void MEDFileMesh::removeGroup(const std::string& name)
581 std::string oname(name);
582 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
583 std::vector<std::string> grps=getGroupsNames();
584 if(it==_groups.end())
586 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
587 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
588 throw INTERP_KERNEL::Exception(oss.str().c_str());
594 * Removes a family from \a this mesh.
595 * \param [in] name - the name of the family to remove.
596 * \throw If no family with such a \a name exists.
598 void MEDFileMesh::removeFamily(const std::string& name)
600 std::string oname(name);
601 std::map<std::string, int >::iterator it=_families.find(oname);
602 std::vector<std::string> fams=getFamiliesNames();
603 if(it==_families.end())
605 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
606 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
607 throw INTERP_KERNEL::Exception(oss.str().c_str());
610 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
612 std::vector<std::string>& v=(*it3).second;
613 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
620 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
621 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
622 * family field whatever its level. This method also suppresses the orphan families.
624 * \return - The list of removed groups names.
626 * \sa MEDFileMesh::removeOrphanFamilies.
628 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
630 removeOrphanFamilies();
631 return removeEmptyGroups();
635 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
636 * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified.
638 * \return - The list of removed families names.
639 * \sa MEDFileMesh::removeOrphanGroups.
641 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
643 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
644 std::vector<std::string> ret;
645 if(!((DataArrayInt*)allFamIdsInUse))
647 ret=getFamiliesNames();
648 _families.clear(); _groups.clear();
651 std::map<std::string,int> famMap;
652 std::map<std::string, std::vector<std::string> > grps(_groups);
653 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
655 if(allFamIdsInUse->presenceOfValue((*it).second))
656 famMap[(*it).first]=(*it).second;
659 ret.push_back((*it).first);
660 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
661 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
663 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
664 std::vector<std::string>& famv=(*it3).second;
665 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
671 { _families=famMap; _groups=grps; }
676 * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever
677 * this family is orphan or not.
679 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
681 void MEDFileMesh::removeFamiliesReferedByNoGroups()
683 std::map<std::string,int> fams;
684 std::set<std::string> sfams;
685 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
686 sfams.insert((*it).first);
687 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
688 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
690 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
691 if(*it!=DFT_FAM_NAME)
692 _families.erase(*it);
696 * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities
697 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
698 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
700 * \sa MEDFileMesh::removeOrphanFamilies
702 void MEDFileMesh::rearrangeFamilies()
704 checkOrphanFamilyZero();
705 removeFamiliesReferedByNoGroups();
707 std::vector<int> levels(getNonEmptyLevelsExt());
708 std::set<int> idsRefed;
709 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
710 idsRefed.insert((*it).second);
711 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
713 const DataArrayInt *fams(0);
716 fams=getFamilyFieldAtLevel(*it);
718 catch(INTERP_KERNEL::Exception& e) { }
721 std::vector<bool> v(fams->getNumberOfTuples(),false);
722 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
723 fams->switchOnTupleEqualTo(*pt,v);
724 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
725 if(!unfetchedIds->empty())
727 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
728 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
729 setFamilyFieldArr(*it,newFams);
732 removeOrphanFamilies();
736 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
738 void MEDFileMesh::checkOrphanFamilyZero() const
740 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
742 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
744 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
745 throw INTERP_KERNEL::Exception(oss.str().c_str());
751 * Renames a group in \a this mesh.
752 * \param [in] oldName - a current name of the group to rename.
753 * \param [in] newName - a new group name.
754 * \throw If no group named \a oldName exists in \a this mesh.
755 * \throw If a group named \a newName already exists.
757 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
759 std::string oname(oldName);
760 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
761 std::vector<std::string> grps=getGroupsNames();
762 if(it==_groups.end())
764 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
765 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
766 throw INTERP_KERNEL::Exception(oss.str().c_str());
768 std::string nname(newName);
769 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
770 if(it2!=_groups.end())
772 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
773 throw INTERP_KERNEL::Exception(oss.str().c_str());
775 std::vector<std::string> cpy=(*it).second;
777 _groups[newName]=cpy;
781 * Changes an id of a family in \a this mesh.
782 * This method calls changeFamilyIdArr().
783 * \param [in] oldId - a current id of the family.
784 * \param [in] newId - a new family id.
786 void MEDFileMesh::changeFamilyId(int oldId, int newId)
788 changeFamilyIdArr(oldId,newId);
789 std::map<std::string,int> fam2;
790 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
792 if((*it).second==oldId)
793 fam2[(*it).first]=newId;
795 fam2[(*it).first]=(*it).second;
801 * Renames a family in \a this mesh.
802 * \param [in] oldName - a current name of the family to rename.
803 * \param [in] newName - a new family name.
804 * \throw If no family named \a oldName exists in \a this mesh.
805 * \throw If a family named \a newName already exists.
807 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
809 std::string oname(oldName);
810 std::map<std::string, int >::iterator it=_families.find(oname);
811 std::vector<std::string> fams=getFamiliesNames();
812 if(it==_families.end())
814 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
815 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
816 throw INTERP_KERNEL::Exception(oss.str().c_str());
818 std::string nname(newName);
819 std::map<std::string, int >::iterator it2=_families.find(nname);
820 if(it2!=_families.end())
822 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
823 throw INTERP_KERNEL::Exception(oss.str().c_str());
825 int cpy=(*it).second;
827 _families[newName]=cpy;
828 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
830 std::vector<std::string>& v=(*it3).second;
831 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
838 * Checks if \a this and another mesh contains the same families.
839 * \param [in] other - the mesh to compare with \a this one.
840 * \param [in,out] what - an unused parameter.
841 * \return bool - \c true if number of families and their ids are the same in the two
842 * meshes. Families with the id == \c 0 are not considered.
844 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
846 if(_families==other->_families)
848 std::map<std::string,int> fam0;
849 std::map<std::string,int> fam1;
850 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
852 fam0[(*it).first]=(*it).second;
853 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
855 fam1[(*it).first]=(*it).second;
860 * Checks if \a this and another mesh contains the same groups.
861 * \param [in] other - the mesh to compare with \a this one.
862 * \param [in,out] what - a string describing a difference of groups of the two meshes
863 * in case if this method returns \c false.
864 * \return bool - \c true if number of groups and families constituting them are the
865 * same in the two meshes.
867 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
869 if(_groups==other->_groups)
872 std::size_t sz=_groups.size();
873 if(sz!=other->_groups.size())
875 what="Groups differ because not same number !\n";
880 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
881 for(std::size_t i=0;i<sz && ret;i++,it1++)
883 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
884 if(it2!=other->_groups.end())
886 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
887 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
893 what="A group in first mesh exists not in other !\n";
899 std::ostringstream oss; oss << "Groups description differs :\n";
900 oss << "First group description :\n";
901 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
903 oss << " Group \"" << (*it).first << "\" on following families :\n";
904 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
905 oss << " \"" << *it2 << "\n";
907 oss << "Second group description :\n";
908 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
910 oss << " Group \"" << (*it).first << "\" on following families :\n";
911 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
912 oss << " \"" << *it2 << "\n";
920 * Checks if a group with a given name exists in \a this mesh.
921 * \param [in] groupName - the group name.
922 * \return bool - \c true the group \a groupName exists in \a this mesh.
924 bool MEDFileMesh::existsGroup(const std::string& groupName) const
926 std::string grpName(groupName);
927 return _groups.find(grpName)!=_groups.end();
931 * Checks if a family with a given id exists in \a this mesh.
932 * \param [in] famId - the family id.
933 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
935 bool MEDFileMesh::existsFamily(int famId) const
937 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
938 if((*it2).second==famId)
944 * Checks if a family with a given name exists in \a this mesh.
945 * \param [in] familyName - the family name.
946 * \return bool - \c true the family \a familyName exists in \a this mesh.
948 bool MEDFileMesh::existsFamily(const std::string& familyName) const
950 std::string fname(familyName);
951 return _families.find(fname)!=_families.end();
955 * Sets an id of a family.
956 * \param [in] familyName - the family name.
957 * \param [in] id - a new id of the family.
959 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
961 std::string fname(familyName);
965 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
967 std::string fname(familyName);
968 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
971 if((*it).first!=familyName)
973 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
974 throw INTERP_KERNEL::Exception(oss.str().c_str());
981 * Adds a family to \a this mesh.
982 * \param [in] familyName - a name of the family.
983 * \param [in] famId - an id of the family.
984 * \throw If a family with the same name or id already exists in \a this mesh.
986 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
988 std::string fname(familyName);
989 std::map<std::string,int>::const_iterator it=_families.find(fname);
990 if(it==_families.end())
992 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
993 if((*it2).second==famId)
995 std::ostringstream oss;
996 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
997 throw INTERP_KERNEL::Exception(oss.str().c_str());
999 _families[fname]=famId;
1003 if((*it).second!=famId)
1005 std::ostringstream oss;
1006 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1007 throw INTERP_KERNEL::Exception(oss.str().c_str());
1013 * Creates a group including all mesh entities of given dimension.
1014 * \warning This method does \b not guarantee that the created group includes mesh
1015 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1016 * present in family fields of different dimensions. To assure this, call
1017 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1018 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1020 * \param [in] groupName - a name of the new group.
1021 * \throw If a group named \a groupName already exists.
1022 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1023 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1025 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1027 std::string grpName(groupName);
1028 std::vector<int> levs=getNonEmptyLevelsExt();
1029 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1031 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1032 oss << "Available relative ext levels are : ";
1033 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1034 throw INTERP_KERNEL::Exception(oss.str().c_str());
1036 if(existsGroup(groupName))
1038 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1039 oss << "Already existing groups are : ";
1040 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1041 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1042 throw INTERP_KERNEL::Exception(oss.str().c_str());
1044 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1046 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1047 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1048 std::vector<std::string> familiesOnWholeGroup;
1049 for(const int *it=famIds->begin();it!=famIds->end();it++)
1052 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1054 _groups[grpName]=familiesOnWholeGroup;
1058 * Ensures that given family ids do not present in family fields of dimensions different
1059 * than given ones. If a family id is present in the family fields of dimensions different
1060 * than the given ones, a new family is created and the whole data is updated accordingly.
1061 * \param [in] famIds - a sequence of family ids to check.
1062 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1063 * famIds should exclusively belong.
1064 * \return bool - \c true if no modification is done in \a this mesh by this method.
1066 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1068 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1069 std::vector<int> levs=getNonEmptyLevelsExt();
1070 std::set<int> levs2(levs.begin(),levs.end());
1071 std::vector<int> levsToTest;
1072 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1073 std::set<int> famIds2(famIds.begin(),famIds.end());
1076 if(!_families.empty())
1077 maxFamId=getMaxFamilyId()+1;
1078 std::vector<std::string> allFams=getFamiliesNames();
1079 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1081 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1084 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1085 std::vector<int> tmp;
1086 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1087 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1090 std::string famName=getFamilyNameGivenId(*it2);
1091 std::ostringstream oss; oss << "Family_" << maxFamId;
1092 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1093 addFamilyOnAllGroupsHaving(famName,zeName);
1094 _families[zeName]=maxFamId;
1095 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1104 * Adds a family to a given group in \a this mesh. If the group with a given name does
1105 * not exist, it is created.
1106 * \param [in] grpName - the name of the group to add the family in.
1107 * \param [in] famName - the name of the family to add to the group named \a grpName.
1108 * \throw If \a grpName or \a famName is an empty string.
1109 * \throw If no family named \a famName is present in \a this mesh.
1111 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1113 std::string grpn(grpName);
1114 std::string famn(famName);
1115 if(grpn.empty() || famn.empty())
1116 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1117 std::vector<std::string> fams=getFamiliesNames();
1118 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1120 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1121 oss << "Create this family or choose an existing one ! Existing fams are : ";
1122 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1123 throw INTERP_KERNEL::Exception(oss.str().c_str());
1125 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1126 if(it==_groups.end())
1128 _groups[grpn].push_back(famn);
1132 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1133 if(it2==(*it).second.end())
1134 (*it).second.push_back(famn);
1139 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1140 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1141 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1143 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1145 std::string famNameCpp(famName);
1146 std::string otherCpp(otherFamName);
1147 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1149 std::vector<std::string>& v=(*it).second;
1150 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1152 v.push_back(otherCpp);
1158 * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
1159 * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed)
1161 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1164 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1165 std::string grpName(ids->getName());
1167 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1168 ids->checkStrictlyMonotonic(true);
1169 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
1170 std::vector<std::string> grpsNames=getGroupsNames();
1171 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1173 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1174 throw INTERP_KERNEL::Exception(oss.str().c_str());
1176 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1177 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1178 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1179 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1180 std::vector<int> familyIds;
1181 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
1182 int maxVal=getTheMaxAbsFamilyId()+1;
1183 std::map<std::string,int> families(_families);
1184 std::map<std::string, std::vector<std::string> > groups(_groups);
1185 std::vector<std::string> fams;
1186 bool created(false);
1187 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1189 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
1190 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1191 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
1192 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1195 bool isFamPresent=false;
1196 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1197 isFamPresent=(*itl)->presenceOfValue(*famId);
1199 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1202 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1203 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1204 fams.push_back(locFamName);
1205 if(existsFamily(*famId))
1207 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1208 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1211 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1215 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1216 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1217 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1218 if(existsFamily(*famId))
1220 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1221 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1226 for(std::size_t i=0;i<familyIds.size();i++)
1228 DataArrayInt *da=idsPerfamiliyIds[i];
1229 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1233 _groups[grpName]=fams;
1236 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1238 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1241 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1243 std::string fam(familyNameToChange);
1244 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1246 std::vector<std::string>& fams((*it).second);
1247 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1251 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1257 * Returns a name of the family having a given id or, if no such a family exists, creates
1258 * a new uniquely named family and returns its name.
1259 * \param [in] id - the id of the family whose name is required.
1260 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1261 * \return std::string - the name of the existing or the created family.
1262 * \throw If it is not possible to create a unique family name.
1264 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1266 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1270 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1271 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1272 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1273 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1275 * This method will throws an exception if it is not possible to create a unique family name.
1277 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1279 std::vector<std::string> famAlreadyExisting(families.size());
1281 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1283 if((*it).second!=id)
1285 famAlreadyExisting[ii]=(*it).first;
1294 std::ostringstream oss; oss << "Family_" << id;
1295 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1301 * Sets names and ids of all families in \a this mesh.
1302 * \param [in] info - a map of a family name to a family id.
1304 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1310 * Sets names of all groups and families constituting them in \a this mesh.
1311 * \param [in] info - a map of a group name to a vector of names of families
1312 * constituting the group.
1314 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1320 * Returns an id of the family having a given name.
1321 * \param [in] name - the name of the family of interest.
1322 * \return int - the id of the family of interest.
1323 * \throw If no family with such a \a name exists.
1325 int MEDFileMesh::getFamilyId(const std::string& name) const
1327 std::string oname(name);
1328 std::map<std::string, int>::const_iterator it=_families.find(oname);
1329 std::vector<std::string> fams=getFamiliesNames();
1330 if(it==_families.end())
1332 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1333 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1334 throw INTERP_KERNEL::Exception(oss.str().c_str());
1336 return (*it).second;
1340 * Returns ids of the families having given names.
1341 * \param [in] fams - a sequence of the names of families of interest.
1342 * \return std::vector<int> - a sequence of the ids of families of interest.
1343 * \throw If \a fams contains a name of an inexistent family.
1345 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1347 std::vector<int> ret(fams.size());
1349 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1351 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1352 if(it2==_families.end())
1354 std::vector<std::string> fams2=getFamiliesNames();
1355 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1356 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1357 throw INTERP_KERNEL::Exception(oss.str().c_str());
1359 ret[i]=(*it2).second;
1365 * Returns a maximal abs(id) of families in \a this mesh.
1366 * \return int - the maximal norm of family id.
1367 * \throw If there are no families in \a this mesh.
1369 int MEDFileMesh::getMaxAbsFamilyId() const
1371 if(_families.empty())
1372 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1373 int ret=-std::numeric_limits<int>::max();
1374 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1376 ret=std::max(std::abs((*it).second),ret);
1382 * Returns a maximal id of families in \a this mesh.
1383 * \return int - the maximal family id.
1384 * \throw If there are no families in \a this mesh.
1386 int MEDFileMesh::getMaxFamilyId() const
1388 if(_families.empty())
1389 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1390 int ret=-std::numeric_limits<int>::max();
1391 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1393 ret=std::max((*it).second,ret);
1399 * Returns a minimal id of families in \a this mesh.
1400 * \return int - the minimal family id.
1401 * \throw If there are no families in \a this mesh.
1403 int MEDFileMesh::getMinFamilyId() const
1405 if(_families.empty())
1406 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1407 int ret=std::numeric_limits<int>::max();
1408 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1410 ret=std::min((*it).second,ret);
1416 * Returns a maximal id of families in \a this mesh. Not only named families are
1417 * considered but all family fields as well.
1418 * \return int - the maximal family id.
1420 int MEDFileMesh::getTheMaxAbsFamilyId() const
1422 int m1=-std::numeric_limits<int>::max();
1423 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1424 m1=std::max(std::abs((*it).second),m1);
1425 int m2=getMaxAbsFamilyIdInArrays();
1426 return std::max(m1,m2);
1430 * Returns a maximal id of families in \a this mesh. Not only named families are
1431 * considered but all family fields as well.
1432 * \return int - the maximal family id.
1434 int MEDFileMesh::getTheMaxFamilyId() const
1436 int m1=-std::numeric_limits<int>::max();
1437 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1438 m1=std::max((*it).second,m1);
1439 int m2=getMaxFamilyIdInArrays();
1440 return std::max(m1,m2);
1444 * Returns a minimal id of families in \a this mesh. Not only named families are
1445 * considered but all family fields as well.
1446 * \return int - the minimal family id.
1448 int MEDFileMesh::getTheMinFamilyId() const
1450 int m1=std::numeric_limits<int>::max();
1451 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1452 m1=std::min((*it).second,m1);
1453 int m2=getMinFamilyIdInArrays();
1454 return std::min(m1,m2);
1458 * This method only considers the maps. The contain of family array is ignored here.
1460 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1462 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1464 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1466 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1467 v.insert((*it).second);
1468 ret->alloc((int)v.size(),1);
1469 std::copy(v.begin(),v.end(),ret->getPointer());
1474 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1476 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1478 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1480 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1481 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1482 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1484 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1485 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1486 if((DataArrayInt *) ret)
1487 ret=dv->buildUnion(ret);
1495 * true is returned if no modification has been needed. false if family
1496 * renumbering has been needed.
1498 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1500 std::vector<int> levs=getNonEmptyLevelsExt();
1501 std::set<int> allFamIds;
1502 int maxId=getMaxFamilyId()+1;
1503 std::map<int,std::vector<int> > famIdsToRenum;
1504 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1506 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1509 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1511 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1513 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1515 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1518 if(famIdsToRenum.empty())
1520 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1521 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1523 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1524 int *famIdsToChange=fam->getPointer();
1525 std::map<int,int> ren;
1526 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1528 if(allIds->presenceOfValue(*it3))
1530 std::string famName=getFamilyNameGivenId(*it3);
1531 std::vector<std::string> grps=getGroupsOnFamily(famName);
1534 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1535 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1536 addFamilyOnGrp((*it4),newFam);
1539 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1540 for(const int *id=ids->begin();id!=ids->end();id++)
1541 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1547 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1548 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1549 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1550 * This method will throw an exception if a same family id is detected in different level.
1551 * \warning This policy is the opposite of those in MED file documentation ...
1553 void MEDFileMesh::normalizeFamIdsTrio()
1555 ensureDifferentFamIdsPerLevel();
1556 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1557 std::vector<int> levs=getNonEmptyLevelsExt();
1558 std::set<int> levsS(levs.begin(),levs.end());
1559 std::set<std::string> famsFetched;
1560 std::map<std::string,int> families;
1561 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1564 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1568 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1569 std::map<int,int> ren;
1570 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1572 int nbOfTuples=fam->getNumberOfTuples();
1573 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1574 for(int *w=start;w!=start+nbOfTuples;w++)
1576 for(const int *it=tmp->begin();it!=tmp->end();it++)
1578 if(allIds->presenceOfValue(*it))
1580 std::string famName=getFamilyNameGivenId(*it);
1581 families[famName]=ren[*it];
1582 famsFetched.insert(famName);
1587 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1590 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1594 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1595 std::map<int,int> ren;
1596 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1598 int nbOfTuples=fam->getNumberOfTuples();
1599 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1600 for(int *w=start;w!=start+nbOfTuples;w++)
1602 for(const int *it=tmp->begin();it!=tmp->end();it++)
1604 if(allIds->presenceOfValue(*it))
1606 std::string famName=getFamilyNameGivenId(*it);
1607 families[famName]=ren[*it];
1608 famsFetched.insert(famName);
1613 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1615 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1618 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1619 fam->fillWithZero();
1620 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1621 if(allIds->presenceOfValue(*it3))
1623 std::string famName=getFamilyNameGivenId(*it3);
1624 families[famName]=0;
1625 famsFetched.insert(famName);
1630 std::vector<std::string> allFams=getFamiliesNames();
1631 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1632 std::set<std::string> unFetchedIds;
1633 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1634 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1635 families[*it4]=_families[*it4];
1640 * This method normalizes fam id with the following policy.
1641 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1642 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1643 * This method will throw an exception if a same family id is detected in different level.
1645 void MEDFileMesh::normalizeFamIdsMEDFile()
1647 ensureDifferentFamIdsPerLevel();
1648 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1649 std::vector<int> levs=getNonEmptyLevelsExt();
1650 std::set<int> levsS(levs.begin(),levs.end());
1651 std::set<std::string> famsFetched;
1652 std::map<std::string,int> families;
1654 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1657 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1660 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1661 std::map<int,int> ren;
1662 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1664 int nbOfTuples=fam->getNumberOfTuples();
1665 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1666 for(int *w=start;w!=start+nbOfTuples;w++)
1668 for(const int *it=tmp->begin();it!=tmp->end();it++)
1670 if(allIds->presenceOfValue(*it))
1672 std::string famName=getFamilyNameGivenId(*it);
1673 families[famName]=ren[*it];
1674 famsFetched.insert(famName);
1680 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1682 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1685 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1686 std::map<int,int> ren;
1687 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1689 int nbOfTuples=fam->getNumberOfTuples();
1690 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1691 for(int *w=start;w!=start+nbOfTuples;w++)
1693 for(const int *it=tmp->begin();it!=tmp->end();it++)
1695 if(allIds->presenceOfValue(*it))
1697 std::string famName=getFamilyNameGivenId(*it);
1698 families[famName]=ren[*it];
1699 famsFetched.insert(famName);
1705 std::vector<std::string> allFams=getFamiliesNames();
1706 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1707 std::set<std::string> unFetchedIds;
1708 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1709 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1710 families[*it4]=_families[*it4];
1715 * Returns a name of the family by its id. If there are several families having the given
1716 * id, the name first in lexical order is returned.
1717 * \param [in] id - the id of the family whose name is required.
1718 * \return std::string - the name of the found family.
1719 * \throw If no family with the given \a id exists.
1721 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1723 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1724 if((*it).second==id)
1726 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1727 throw INTERP_KERNEL::Exception(oss.str().c_str());
1731 * Returns a string describing \a this mesh. This description includes the mesh name and
1732 * the mesh description string.
1733 * \return std::string - the mesh information string.
1735 std::string MEDFileMesh::simpleRepr() const
1737 std::ostringstream oss;
1738 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1739 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1740 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1745 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1746 * an empty one is created.
1748 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1750 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1753 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
1754 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1755 arr->fillWithZero();
1756 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1757 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1761 * Returns ids of mesh entities contained in a given group of a given dimension.
1762 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1764 * \param [in] grp - the name of the group of interest.
1765 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1766 * returned instead of ids.
1767 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1768 * numbers, if available and required, of mesh entities of the group. The caller
1769 * is to delete this array using decrRef() as it is no more needed.
1770 * \throw If the name of a nonexistent group is specified.
1771 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1773 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1775 std::vector<std::string> tmp(1);
1777 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1783 * Returns ids of mesh entities contained in given groups of a given dimension.
1784 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1786 * \param [in] grps - the names of the groups of interest.
1787 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1788 * returned instead of ids.
1789 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1790 * numbers, if available and required, of mesh entities of the groups. The caller
1791 * is to delete this array using decrRef() as it is no more needed.
1792 * \throw If the name of a nonexistent group is present in \a grps.
1793 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1795 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1797 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1798 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1802 * Returns ids of mesh entities contained in a given family of a given dimension.
1803 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1805 * \param [in] fam - the name of the family of interest.
1806 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1807 * returned instead of ids.
1808 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1809 * numbers, if available and required, of mesh entities of the family. The caller
1810 * is to delete this array using decrRef() as it is no more needed.
1811 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1813 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1815 std::vector<std::string> tmp(1);
1817 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1823 * Returns ids of nodes contained in a given group.
1824 * \param [in] grp - the name of the group of interest.
1825 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1826 * returned instead of ids.
1827 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1828 * numbers, if available and required, of nodes of the group. The caller
1829 * is to delete this array using decrRef() as it is no more needed.
1830 * \throw If the name of a nonexistent group is specified.
1831 * \throw If the family field is missing for nodes.
1833 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1835 std::vector<std::string> tmp(1);
1837 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1843 * Returns ids of nodes contained in given groups.
1844 * \param [in] grps - the names of the groups of interest.
1845 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1846 * returned instead of ids.
1847 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1848 * numbers, if available and required, of nodes of the groups. The caller
1849 * is to delete this array using decrRef() as it is no more needed.
1850 * \throw If the name of a nonexistent group is present in \a grps.
1851 * \throw If the family field is missing for nodes.
1853 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1855 return getGroupsArr(1,grps,renum);
1859 * Returns ids of nodes contained in a given group.
1860 * \param [in] grp - the name of the group of interest.
1861 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1862 * returned instead of ids.
1863 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1864 * numbers, if available and required, of nodes of the group. The caller
1865 * is to delete this array using decrRef() as it is no more needed.
1866 * \throw If the name of a nonexistent group is specified.
1867 * \throw If the family field is missing for nodes.
1869 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1871 std::vector<std::string> tmp(1);
1873 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1879 * Returns ids of nodes contained in given families.
1880 * \param [in] fams - the names of the families of interest.
1881 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1882 * returned instead of ids.
1883 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1884 * numbers, if available and required, of nodes of the families. The caller
1885 * is to delete this array using decrRef() as it is no more needed.
1886 * \throw If the family field is missing for nodes.
1888 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1890 return getFamiliesArr(1,fams,renum);
1894 * Adds groups of given dimension and creates corresponding families and family fields
1895 * given ids of mesh entities of each group.
1896 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1897 * \param [in] grps - a sequence of arrays of ids each describing a group.
1898 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1900 * \throw If names of some groups in \a grps are equal.
1901 * \throw If \a grps includes a group with an empty name.
1902 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1903 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1905 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1909 std::set<std::string> grpsName;
1910 std::vector<std::string> grpsName2(grps.size());
1913 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1915 grpsName.insert((*it)->getName());
1916 grpsName2[i]=(*it)->getName();
1918 if(grpsName.size()!=grps.size())
1919 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1920 if(grpsName.find(std::string(""))!=grpsName.end())
1921 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1922 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1923 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1924 std::vector< std::vector<int> > fidsOfGroups;
1927 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1931 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1932 for(unsigned int ii=0;ii<grps.size();ii++)
1934 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1935 grps2[ii]->setName(grps[ii]->getName());
1937 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1938 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1941 if(!_families.empty())
1942 offset=getMaxAbsFamilyId()+1;
1943 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1944 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1945 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1946 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1950 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1951 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1952 * For the moment, the two last input parameters are not taken into account.
1954 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1956 std::map<int,std::string> famInv;
1957 for(const int *it=famIds->begin();it!=famIds->end();it++)
1959 std::ostringstream oss;
1960 oss << "Family_" << (*it);
1961 _families[oss.str()]=(*it);
1962 famInv[*it]=oss.str();
1965 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1967 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1969 _groups[grpNames[i]].push_back(famInv[*it2]);
1974 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1976 std::vector<int> levs(getNonEmptyLevels());
1977 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1978 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1980 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1981 ret.insert(ret.end(),elts.begin(),elts.end());
1986 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1988 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1989 return mLev->getDistributionOfTypes();
1992 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
1994 loadLL(fid,mName,dt,it,mrs);
1995 loadJointsFromFile(fid);
1996 loadEquivalences(fid);
1999 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2001 famArr->applyLin(offset>0?1:-1,offset,0);
2002 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2005 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2006 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2011 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2012 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2013 * If this method fails to find such a name it will throw an exception.
2015 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2018 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2021 std::size_t len=nameTry.length();
2022 for(std::size_t ii=1;ii<len;ii++)
2024 std::string tmp=nameTry.substr(ii,len-ii);
2025 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2031 for(std::size_t i=1;i<30;i++)
2033 std::string tmp1(nameTry.at(0),i);
2035 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2041 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2043 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2045 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2048 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2050 std::size_t nbOfChunks=code.size()/3;
2051 if(code.size()%3!=0)
2052 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2054 for(std::size_t i=0;i<nbOfChunks;i++)
2063 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2064 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2065 * If _name is not empty and that 'm' has the same name nothing is done.
2066 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2068 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2071 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2076 std::string name(m->getName());
2081 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2082 oss << name << "' ! Names must match !";
2083 throw INTERP_KERNEL::Exception(oss.str().c_str());
2087 if(_desc_name.empty())
2088 _desc_name=m->getDescription();
2091 std::string name(m->getDescription());
2094 if(_desc_name!=name)
2096 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2097 oss << name << "' ! Names must match !";
2098 throw INTERP_KERNEL::Exception(oss.str().c_str());
2104 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2106 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2107 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2109 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2110 oss << " - Groups lying on this family : ";
2111 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2112 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2113 oss << std::endl << std::endl;
2118 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2119 * file. The mesh to load is specified by its name and numbers of a time step and an
2121 * \param [in] fileName - the name of MED file to read.
2122 * \param [in] mName - the name of the mesh to read.
2123 * \param [in] dt - the number of a time step.
2124 * \param [in] it - the number of an iteration.
2125 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2126 * mesh using decrRef() as it is no more needed.
2127 * \throw If the file is not readable.
2128 * \throw If there is no mesh with given attributes in the file.
2129 * \throw If the mesh in the file is not an unstructured one.
2131 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2133 MEDFileUtilities::CheckFileForRead(fileName);
2134 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2135 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2139 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2140 * file. The first mesh in the file is loaded.
2141 * \param [in] fileName - the name of MED file to read.
2142 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2143 * mesh using decrRef() as it is no more needed.
2144 * \throw If the file is not readable.
2145 * \throw If there is no meshes in the file.
2146 * \throw If the mesh in the file is not an unstructured one.
2148 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2150 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2153 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2154 throw INTERP_KERNEL::Exception(oss.str().c_str());
2156 MEDFileUtilities::CheckFileForRead(fileName);
2157 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2159 ParaMEDMEM::MEDCouplingMeshType meshType;
2161 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
2162 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2166 * Returns an empty instance of MEDFileUMesh.
2167 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2168 * mesh using decrRef() as it is no more needed.
2170 MEDFileUMesh *MEDFileUMesh::New()
2172 return new MEDFileUMesh;
2176 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2177 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2178 * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh.
2179 * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce
2180 * at most the memory consumtion.
2182 * \param [in] fileName - the name of the file.
2183 * \param [in] mName - the name of the mesh to be read.
2184 * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
2185 * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
2186 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2187 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2188 * \param [in] mrs - the request for what to be loaded.
2189 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2191 MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2193 MEDFileUtilities::CheckFileForRead(fileName);
2194 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2195 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2199 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2200 * This method is \b NOT wrapped into python.
2202 MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2204 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2205 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2209 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2211 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2212 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2216 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2218 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2219 ret.push_back((const DataArrayDouble*)_coords);
2220 ret.push_back((const DataArrayInt *)_fam_coords);
2221 ret.push_back((const DataArrayInt *)_num_coords);
2222 ret.push_back((const DataArrayInt *)_rev_num_coords);
2223 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2224 ret.push_back((const PartDefinition *)_part_coords);
2225 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2226 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2230 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2232 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2236 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2238 return new MEDFileUMesh;
2241 MEDFileMesh *MEDFileUMesh::deepCpy() const
2243 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2244 ret->deepCpyEquivalences(*this);
2245 if((const DataArrayDouble*)_coords)
2246 ret->_coords=_coords->deepCpy();
2247 if((const DataArrayInt*)_fam_coords)
2248 ret->_fam_coords=_fam_coords->deepCpy();
2249 if((const DataArrayInt*)_num_coords)
2250 ret->_num_coords=_num_coords->deepCpy();
2251 if((const DataArrayInt*)_rev_num_coords)
2252 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2253 if((const DataArrayAsciiChar*)_name_coords)
2254 ret->_name_coords=_name_coords->deepCpy();
2256 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2258 if((const MEDFileUMeshSplitL1 *)(*it))
2259 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2261 if((const PartDefinition*)_part_coords)
2262 ret->_part_coords=_part_coords->deepCpy();
2267 * Checks if \a this and another mesh are equal.
2268 * \param [in] other - the mesh to compare with.
2269 * \param [in] eps - a precision used to compare real values.
2270 * \param [in,out] what - the string returning description of unequal data.
2271 * \return bool - \c true if the meshes are equal, \c false, else.
2273 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2275 if(!MEDFileMesh::isEqual(other,eps,what))
2277 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2280 what="Mesh types differ ! This is unstructured and other is NOT !";
2283 clearNonDiscrAttributes();
2284 otherC->clearNonDiscrAttributes();
2285 const DataArrayDouble *coo1=_coords;
2286 const DataArrayDouble *coo2=otherC->_coords;
2287 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2289 what="Mismatch of coordinates ! One is defined and not other !";
2294 bool ret=coo1->isEqual(*coo2,eps);
2297 what="Coords differ !";
2301 const DataArrayInt *famc1=_fam_coords;
2302 const DataArrayInt *famc2=otherC->_fam_coords;
2303 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2305 what="Mismatch of families arr on nodes ! One is defined and not other !";
2310 bool ret=famc1->isEqual(*famc2);
2313 what="Families arr on node differ !";
2317 const DataArrayInt *numc1=_num_coords;
2318 const DataArrayInt *numc2=otherC->_num_coords;
2319 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2321 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2326 bool ret=numc1->isEqual(*numc2);
2329 what="Numbering arr on node differ !";
2333 const DataArrayAsciiChar *namec1=_name_coords;
2334 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2335 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2337 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2342 bool ret=namec1->isEqual(*namec2);
2345 what="Names arr on node differ !";
2349 if(_ms.size()!=otherC->_ms.size())
2351 what="Number of levels differs !";
2354 std::size_t sz=_ms.size();
2355 for(std::size_t i=0;i<sz;i++)
2357 const MEDFileUMeshSplitL1 *s1=_ms[i];
2358 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2359 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2361 what="Mismatch of presence of sub levels !";
2366 bool ret=s1->isEqual(s2,eps,what);
2371 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2374 if((!pd0 && pd1) || (pd0 && !pd1))
2376 what=std::string("node part def is defined only for one among this or other !");
2379 return pd0->isEqual(pd1,what);
2383 * Clears redundant attributes of incorporated data arrays.
2385 void MEDFileUMesh::clearNonDiscrAttributes() const
2387 MEDFileMesh::clearNonDiscrAttributes();
2388 const DataArrayDouble *coo1=_coords;
2390 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2391 const DataArrayInt *famc1=_fam_coords;
2393 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2394 const DataArrayInt *numc1=_num_coords;
2396 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2397 const DataArrayAsciiChar *namc1=_name_coords;
2399 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2400 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2402 const MEDFileUMeshSplitL1 *tmp=(*it);
2404 tmp->clearNonDiscrAttributes();
2408 void MEDFileUMesh::setName(const std::string& name)
2410 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2411 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2412 (*it)->setName(name);
2413 MEDFileMesh::setName(name);
2416 MEDFileUMesh::MEDFileUMesh()
2420 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2423 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2425 catch(INTERP_KERNEL::Exception& e)
2431 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2432 * See MEDFileUMesh::LoadPartOf for detailed description.
2436 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2438 MEDFileUMeshL2 loaderl2;
2439 ParaMEDMEM::MEDCouplingMeshType meshType;
2442 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2443 if(meshType!=UNSTRUCTURED)
2445 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2446 throw INTERP_KERNEL::Exception(oss.str().c_str());
2448 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2449 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2453 * \brief Write joints in a file
2455 void MEDFileMesh::writeJoints(med_idt fid) const
2457 if ( (const MEDFileJoints*) _joints )
2458 _joints->write(fid);
2462 * \brief Load joints in a file or use provided ones
2464 //================================================================================
2466 * \brief Load joints in a file or use provided ones
2467 * \param [in] fid - MED file descriptor
2468 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2469 * Usually this joints are those just read by another iteration
2470 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2472 //================================================================================
2474 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2476 if ( toUseInstedOfReading )
2477 setJoints( toUseInstedOfReading );
2479 _joints = MEDFileJoints::New( fid, _name );
2482 void MEDFileMesh::loadEquivalences(med_idt fid)
2484 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2486 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2489 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2491 const MEDFileEquivalences *equiv(other._equiv);
2493 _equiv=equiv->deepCpy(this);
2496 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2498 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2499 if(!thisEq && !otherEq)
2501 if(thisEq && otherEq)
2502 return thisEq->isEqual(otherEq,what);
2505 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2510 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2512 const MEDFileEquivalences *equiv(_equiv);
2515 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2516 _equiv->getRepr(oss);
2520 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2522 int MEDFileMesh::getNumberOfJoints() const
2524 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2528 * \brief Return joints with all adjacent mesh domains
2530 MEDFileJoints * MEDFileMesh::getJoints() const
2532 return const_cast<MEDFileJoints*>(& (*_joints));
2535 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2537 if ( joints != _joints )
2546 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2548 * \sa loadPartUMeshFromFile
2550 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2552 MEDFileUMeshL2 loaderl2;
2553 ParaMEDMEM::MEDCouplingMeshType meshType;
2556 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2557 if(meshType!=UNSTRUCTURED)
2559 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2560 throw INTERP_KERNEL::Exception(oss.str().c_str());
2562 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2563 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2566 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2568 int lev=loaderl2.getNumberOfLevels();
2570 for(int i=0;i<lev;i++)
2572 if(!loaderl2.emptyLev(i))
2573 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2577 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2579 setName(loaderl2.getName());
2580 setDescription(loaderl2.getDescription());
2581 setUnivName(loaderl2.getUnivName());
2582 setIteration(loaderl2.getIteration());
2583 setOrder(loaderl2.getOrder());
2584 setTimeValue(loaderl2.getTime());
2585 setTimeUnit(loaderl2.getTimeUnit());
2586 _coords=loaderl2.getCoords();
2587 if(!mrs || mrs->isNodeFamilyFieldReading())
2588 _fam_coords=loaderl2.getCoordsFamily();
2589 if(!mrs || mrs->isNodeNumFieldReading())
2590 _num_coords=loaderl2.getCoordsNum();
2591 if(!mrs || mrs->isNodeNameFieldReading())
2592 _name_coords=loaderl2.getCoordsName();
2593 _part_coords=loaderl2.getPartDefOfCoo();
2597 MEDFileUMesh::~MEDFileUMesh()
2601 void MEDFileUMesh::writeLL(med_idt fid) const
2603 const DataArrayDouble *coo=_coords;
2604 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2605 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2606 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2607 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2608 int spaceDim=coo?coo->getNumberOfComponents():0;
2611 mdim=getMeshDimension();
2612 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2613 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2614 for(int i=0;i<spaceDim;i++)
2616 std::string info=coo->getInfoOnComponent(i);
2618 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2619 MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2620 MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2622 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
2624 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2625 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2626 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2627 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2628 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2629 (*it)->write(fid,meshName,mdim);
2630 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2634 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2635 * \return std::vector<int> - a sequence of the relative dimensions.
2637 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2639 std::vector<int> ret;
2641 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2642 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2649 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2650 * \return std::vector<int> - a sequence of the relative dimensions.
2652 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2654 std::vector<int> ret0=getNonEmptyLevels();
2655 if((const DataArrayDouble *) _coords)
2657 std::vector<int> ret(ret0.size()+1);
2659 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2665 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2667 std::vector<int> ret;
2668 const DataArrayInt *famCoo(_fam_coords);
2672 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2674 const MEDFileUMeshSplitL1 *cur(*it);
2676 if(cur->getFamilyField())
2682 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2684 std::vector<int> ret;
2685 const DataArrayInt *numCoo(_num_coords);
2689 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2691 const MEDFileUMeshSplitL1 *cur(*it);
2693 if(cur->getNumberField())
2699 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2701 std::vector<int> ret;
2702 const DataArrayAsciiChar *nameCoo(_name_coords);
2706 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2708 const MEDFileUMeshSplitL1 *cur(*it);
2710 if(cur->getNameField())
2717 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2718 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2719 * \param [in] grp - the name of the group of interest.
2720 * \return std::vector<int> - a sequence of the relative dimensions.
2722 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2724 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2725 return getFamsNonEmptyLevels(fams);
2729 * Returns all relative mesh levels (including nodes) where a given group is defined.
2730 * \param [in] grp - the name of the group of interest.
2731 * \return std::vector<int> - a sequence of the relative dimensions.
2733 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2735 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2736 return getFamsNonEmptyLevelsExt(fams);
2740 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2741 * To include nodes, call getFamNonEmptyLevelsExt() method.
2742 * \param [in] fam - the name of the family of interest.
2743 * \return std::vector<int> - a sequence of the relative dimensions.
2745 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2747 std::vector<std::string> fams(1,std::string(fam));
2748 return getFamsNonEmptyLevels(fams);
2752 * Returns all relative mesh levels (including nodes) where a given family is defined.
2753 * \param [in] fam - the name of the family of interest.
2754 * \return std::vector<int> - a sequence of the relative dimensions.
2756 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2758 std::vector<std::string> fams(1,std::string(fam));
2759 return getFamsNonEmptyLevelsExt(fams);
2763 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2764 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2765 * \param [in] grps - a sequence of names of the groups of interest.
2766 * \return std::vector<int> - a sequence of the relative dimensions.
2768 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2770 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2771 return getFamsNonEmptyLevels(fams);
2775 * Returns all relative mesh levels (including nodes) where given groups are defined.
2776 * \param [in] grps - a sequence of names of the groups of interest.
2777 * \return std::vector<int> - a sequence of the relative dimensions.
2779 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2781 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2782 return getFamsNonEmptyLevelsExt(fams);
2786 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2787 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2788 * \param [in] fams - the name of the family of interest.
2789 * \return std::vector<int> - a sequence of the relative dimensions.
2791 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2793 std::vector<int> ret;
2794 std::vector<int> levs=getNonEmptyLevels();
2795 std::vector<int> famIds=getFamiliesIds(fams);
2796 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2797 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2803 * Returns all relative mesh levels (including nodes) where given families are defined.
2804 * \param [in] fams - the names of the families of interest.
2805 * \return std::vector<int> - a sequence of the relative dimensions.
2807 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2809 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2810 const DataArrayInt *famCoords=_fam_coords;
2813 std::vector<int> famIds=getFamiliesIds(fams);
2814 if(famCoords->presenceOfValue(famIds))
2816 std::vector<int> ret(ret0.size()+1);
2818 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2826 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2827 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2828 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2831 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2833 std::vector<std::string> ret;
2834 std::vector<std::string> allGrps=getGroupsNames();
2835 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2837 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2838 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2844 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2846 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2847 if((const DataArrayInt *)_fam_coords)
2849 int val=_fam_coords->getMaxValue(tmp);
2850 ret=std::max(ret,std::abs(val));
2852 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2854 if((const MEDFileUMeshSplitL1 *)(*it))
2856 const DataArrayInt *da=(*it)->getFamilyField();
2859 int val=da->getMaxValue(tmp);
2860 ret=std::max(ret,std::abs(val));
2867 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2869 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2870 if((const DataArrayInt *)_fam_coords)
2872 int val=_fam_coords->getMaxValue(tmp);
2873 ret=std::max(ret,val);
2875 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2877 if((const MEDFileUMeshSplitL1 *)(*it))
2879 const DataArrayInt *da=(*it)->getFamilyField();
2882 int val=da->getMaxValue(tmp);
2883 ret=std::max(ret,val);
2890 int MEDFileUMesh::getMinFamilyIdInArrays() const
2892 int ret=std::numeric_limits<int>::max(),tmp=-1;
2893 if((const DataArrayInt *)_fam_coords)
2895 int val=_fam_coords->getMinValue(tmp);
2896 ret=std::min(ret,val);
2898 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2900 if((const MEDFileUMeshSplitL1 *)(*it))
2902 const DataArrayInt *da=(*it)->getFamilyField();
2905 int val=da->getMinValue(tmp);
2906 ret=std::min(ret,val);
2914 * Returns the dimension on cells in \a this mesh.
2915 * \return int - the mesh dimension.
2916 * \throw If there are no cells in this mesh.
2918 int MEDFileUMesh::getMeshDimension() const
2921 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2922 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2923 return (*it)->getMeshDimension()+lev;
2924 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2928 * Returns the space dimension of \a this mesh that is equal to number of components in
2929 * the node coordinates array.
2930 * \return int - the space dimension of \a this mesh.
2931 * \throw If the node coordinates array is not available.
2933 int MEDFileUMesh::getSpaceDimension() const
2935 const DataArrayDouble *coo=_coords;
2937 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2938 return coo->getNumberOfComponents();
2942 * Returns a string describing \a this mesh.
2943 * \return std::string - the mesh information string.
2945 std::string MEDFileUMesh::simpleRepr() const
2947 std::ostringstream oss;
2948 oss << MEDFileMesh::simpleRepr();
2949 const DataArrayDouble *coo=_coords;
2950 oss << "- The dimension of the space is ";
2951 static const char MSG1[]= "*** NO COORDS SET ***";
2952 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2954 oss << _coords->getNumberOfComponents() << std::endl;
2956 oss << MSG1 << std::endl;
2957 oss << "- Type of the mesh : UNSTRUCTURED\n";
2958 oss << "- Number of nodes : ";
2960 oss << _coords->getNumberOfTuples() << std::endl;
2962 oss << MSG1 << std::endl;
2963 std::size_t nbOfLev=_ms.size();
2964 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2965 for(std::size_t i=0;i<nbOfLev;i++)
2967 const MEDFileUMeshSplitL1 *lev=_ms[i];
2968 oss << " - Level #" << -((int) i) << " has dimension : ";
2971 oss << lev->getMeshDimension() << std::endl;
2972 lev->simpleRepr(oss);
2975 oss << MSG2 << std::endl;
2977 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2980 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2981 oss << "- Names of coordinates :" << std::endl;
2982 std::vector<std::string> vars=coo->getVarsOnComponent();
2983 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2984 oss << std::endl << "- Units of coordinates : " << std::endl;
2985 std::vector<std::string> units=coo->getUnitsOnComponent();
2986 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2988 oss << std::endl << std::endl;
2990 getEquivalencesRepr(oss);
2995 * Returns a full textual description of \a this mesh.
2996 * \return std::string - the string holding the mesh description.
2998 std::string MEDFileUMesh::advancedRepr() const
3000 return simpleRepr();
3004 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3005 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3006 * \return int - the number of entities.
3007 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3009 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3011 if(meshDimRelToMaxExt==1)
3013 if(!((const DataArrayDouble *)_coords))
3014 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3015 return _coords->getNumberOfTuples();
3017 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3021 * Returns the family field for mesh entities of a given dimension.
3022 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3023 * \return const DataArrayInt * - the family field. It is an array of ids of families
3024 * each mesh entity belongs to. It can be \c NULL.
3026 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3028 if(meshDimRelToMaxExt==1)
3030 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3031 return l1->getFamilyField();
3034 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3036 if(meshDimRelToMaxExt==1)
3038 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3039 return l1->getFamilyField();
3043 * Returns the optional numbers of mesh entities of a given dimension.
3044 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3045 * \return const DataArrayInt * - the array of the entity numbers.
3046 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3048 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3050 if(meshDimRelToMaxExt==1)
3052 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3053 return l1->getNumberField();
3056 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3058 if(meshDimRelToMaxExt==1)
3059 return _name_coords;
3060 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3061 return l1->getNameField();
3065 * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file).
3067 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3068 * \param [in] gt - The input geometric type for which the part definition is requested.
3069 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3071 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3073 if(meshDimRelToMaxExt==1)
3074 return _part_coords;
3075 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3076 return l1->getPartDef(gt);
3079 int MEDFileUMesh::getNumberOfNodes() const
3081 const DataArrayDouble *coo(_coords);
3083 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3084 return coo->getNumberOfTuples();
3087 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3089 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3090 return l1->getNumberOfCells();
3093 bool MEDFileUMesh::hasImplicitPart() const
3098 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3100 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3103 void MEDFileUMesh::releaseImplicitPartIfAny() const
3107 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3109 std::size_t sz(st.getNumberOfItems());
3110 for(std::size_t i=0;i<sz;i++)
3112 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3113 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3114 if(st[i].getPflName().empty())
3115 m->computeNodeIdsAlg(nodesFetched);
3118 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3119 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3120 m2->computeNodeIdsAlg(nodesFetched);
3126 * Returns the optional numbers of mesh entities of a given dimension transformed using
3127 * DataArrayInt::invertArrayN2O2O2N().
3128 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3129 * \return const DataArrayInt * - the array of the entity numbers transformed using
3130 * DataArrayInt::invertArrayN2O2O2N().
3131 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3133 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3135 if(meshDimRelToMaxExt==1)
3137 if(!((const DataArrayInt *)_num_coords))
3138 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3139 return _rev_num_coords;
3141 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3142 return l1->getRevNumberField();
3146 * Returns a pointer to the node coordinates array of \a this mesh \b without
3147 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3149 DataArrayDouble *MEDFileUMesh::getCoords() const
3151 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
3152 if((DataArrayDouble *)tmp)
3160 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3161 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3163 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3164 * \param [in] grp - the name of the group whose mesh entities are included in the
3166 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3167 * according to the optional numbers of entities, if available.
3168 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3169 * delete this mesh using decrRef() as it is no more needed.
3170 * \throw If the name of a nonexistent group is specified.
3171 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3173 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3175 synchronizeTinyInfoOnLeaves();
3176 std::vector<std::string> tmp(1);
3178 return getGroups(meshDimRelToMaxExt,tmp,renum);
3182 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3183 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3185 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3186 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3188 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3189 * according to the optional numbers of entities, if available.
3190 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3191 * delete this mesh using decrRef() as it is no more needed.
3192 * \throw If a name of a nonexistent group is present in \a grps.
3193 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3195 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3197 synchronizeTinyInfoOnLeaves();
3198 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3199 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3200 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3201 zeRet->setName(grps[0]);
3202 return zeRet.retn();
3206 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3207 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3209 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3210 * \param [in] fam - the name of the family whose mesh entities are included in the
3212 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3213 * according to the optional numbers of entities, if available.
3214 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3215 * delete this mesh using decrRef() as it is no more needed.
3216 * \throw If a name of a nonexistent family is present in \a grps.
3217 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3219 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3221 synchronizeTinyInfoOnLeaves();
3222 std::vector<std::string> tmp(1);
3224 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3228 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3229 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3231 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3232 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3234 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3235 * according to the optional numbers of entities, if available.
3236 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3237 * delete this mesh using decrRef() as it is no more needed.
3238 * \throw If a name of a nonexistent family is present in \a fams.
3239 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3241 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3243 synchronizeTinyInfoOnLeaves();
3244 if(meshDimRelToMaxExt==1)
3246 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3247 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3248 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3252 std::vector<int> famIds=getFamiliesIds(fams);
3253 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3254 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3256 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3258 zeRet=l1->getFamilyPart(0,0,renum);
3259 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3260 zeRet->setName(fams[0]);
3261 return zeRet.retn();
3265 * Returns ids of mesh entities contained in given families of a given dimension.
3266 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3268 * \param [in] fams - the names of the families of interest.
3269 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3270 * returned instead of ids.
3271 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3272 * numbers, if available and required, of mesh entities of the families. The caller
3273 * is to delete this array using decrRef() as it is no more needed.
3274 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3276 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3278 std::vector<int> famIds=getFamiliesIds(fams);
3279 if(meshDimRelToMaxExt==1)
3281 if((const DataArrayInt *)_fam_coords)
3283 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3285 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3287 da=_fam_coords->getIdsEqualList(0,0);
3289 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3294 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3296 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3298 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3300 return l1->getFamilyPartArr(0,0,renum);
3304 * Returns a MEDCouplingUMesh of a given relative dimension.
3305 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3306 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3307 * To build a valid MEDCouplingUMesh from the returned one in this case,
3308 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3309 * \param [in] meshDimRelToMax - the relative dimension of interest.
3310 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3311 * optional numbers of mesh entities.
3312 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3313 * delete using decrRef() as it is no more needed.
3314 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3315 * \sa getGenMeshAtLevel()
3317 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3319 synchronizeTinyInfoOnLeaves();
3320 if(meshDimRelToMaxExt==1)
3324 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3325 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3326 umesh->setCoords(cc);
3327 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3328 umesh->setName(getName());
3332 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3333 return l1->getWholeMesh(renum);
3337 * Returns a MEDCouplingUMesh of a given relative dimension.
3338 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3339 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3340 * To build a valid MEDCouplingUMesh from the returned one in this case,
3341 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3342 * \param [in] meshDimRelToMax - the relative dimension of interest.
3343 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3344 * optional numbers of mesh entities.
3345 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3346 * delete using decrRef() as it is no more needed.
3347 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3348 * \sa getMeshAtLevel()
3350 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3352 return getMeshAtLevel(meshDimRelToMax,renum);
3355 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3357 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3358 return l1->getDistributionOfTypes();
3362 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3363 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3364 * optional numbers of mesh entities.
3365 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3366 * delete using decrRef() as it is no more needed.
3367 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3369 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3371 return getMeshAtLevel(0,renum);
3375 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3376 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3377 * optional numbers of mesh entities.
3378 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3379 * delete using decrRef() as it is no more needed.
3380 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3382 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3384 return getMeshAtLevel(-1,renum);
3388 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3389 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3390 * optional numbers of mesh entities.
3391 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3392 * delete using decrRef() as it is no more needed.
3393 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3395 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3397 return getMeshAtLevel(-2,renum);
3401 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3402 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3403 * optional numbers of mesh entities.
3404 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3405 * delete using decrRef() as it is no more needed.
3406 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3408 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3410 return getMeshAtLevel(-3,renum);
3414 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3415 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3416 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3417 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3419 void MEDFileUMesh::forceComputationOfParts() const
3421 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3423 const MEDFileUMeshSplitL1 *elt(*it);
3425 elt->forceComputationOfParts();
3430 * This method returns a vector of mesh parts containing each exactly one geometric type.
3431 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3432 * This method is only for memory aware users.
3433 * The returned pointers are **NOT** new object pointer. No need to mange them.
3435 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3437 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3438 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3442 * This method returns the part of \a this having the geometric type \a gt.
3443 * If such part is not existing an exception will be thrown.
3444 * The returned pointer is **NOT** new object pointer. No need to mange it.
3446 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3448 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3449 int lev=(int)cm.getDimension()-getMeshDimension();
3450 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3451 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3455 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3456 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3458 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3460 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3461 return sp->getGeoTypes();
3464 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3466 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3467 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3468 return sp->getNumberOfCellsWithType(ct);
3472 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3473 * \param [in] gt - the geometric type for which the family field is asked.
3474 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3475 * delete using decrRef() as it is no more needed.
3476 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3478 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3480 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3481 int lev=(int)cm.getDimension()-getMeshDimension();
3482 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3483 return sp->extractFamilyFieldOnGeoType(gt);
3487 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3488 * \param [in] gt - the geometric type for which the number field is asked.
3489 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3490 * delete using decrRef() as it is no more needed.
3491 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3493 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3495 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3496 int lev=(int)cm.getDimension()-getMeshDimension();
3497 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3498 return sp->extractNumberFieldOnGeoType(gt);
3502 * This method returns for specified geometric type \a gt the relative level to \a this.
3503 * If the relative level is empty an exception will be thrown.
3505 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3507 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3508 int ret((int)cm.getDimension()-getMeshDimension());
3509 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3513 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3515 if(meshDimRelToMaxExt==1)
3516 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3517 if(meshDimRelToMaxExt>1)
3518 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3519 int tracucedRk=-meshDimRelToMaxExt;
3520 if(tracucedRk>=(int)_ms.size())
3521 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3522 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3523 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3524 return _ms[tracucedRk];
3527 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3529 if(meshDimRelToMaxExt==1)
3530 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3531 if(meshDimRelToMaxExt>1)
3532 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3533 int tracucedRk=-meshDimRelToMaxExt;
3534 if(tracucedRk>=(int)_ms.size())
3535 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3536 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3537 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3538 return _ms[tracucedRk];
3541 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3543 if(-meshDimRelToMax>=(int)_ms.size())
3544 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3546 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3548 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3550 int ref=(*it)->getMeshDimension();
3551 if(ref+i!=meshDim-meshDimRelToMax)
3552 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3558 * Sets the node coordinates array of \a this mesh.
3559 * \param [in] coords - the new node coordinates array.
3560 * \throw If \a coords == \c NULL.
3562 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3565 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3566 coords->checkAllocated();
3567 int nbOfTuples=coords->getNumberOfTuples();
3570 _fam_coords=DataArrayInt::New();
3571 _fam_coords->alloc(nbOfTuples,1);
3572 _fam_coords->fillWithZero();
3573 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3574 if((MEDFileUMeshSplitL1 *)(*it))
3575 (*it)->setCoords(coords);
3579 * Removes all groups of a given dimension in \a this mesh.
3580 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3581 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3583 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3585 if(meshDimRelToMaxExt==1)
3587 if((DataArrayInt *)_fam_coords)
3588 _fam_coords->fillWithZero();
3591 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3592 l1->eraseFamilyField();
3597 * Removes all families with ids not present in the family fields of \a this mesh.
3599 void MEDFileUMesh::optimizeFamilies()
3601 std::vector<int> levs=getNonEmptyLevelsExt();
3602 std::set<int> allFamsIds;
3603 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3605 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3606 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3608 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3611 std::set<std::string> famNamesToKill;
3612 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3614 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3615 famNamesToKill.insert((*it).first);
3617 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3618 _families.erase(*it);
3619 std::vector<std::string> grpNamesToKill;
3620 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3622 std::vector<std::string> tmp;
3623 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3625 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3626 tmp.push_back(*it2);
3631 tmp.push_back((*it).first);
3633 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3638 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3639 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3640 * The boundary is built according to the following method:
3641 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3642 * coordinates array is extended).
3643 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated.
3644 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3645 * other side of the group is no more a neighbor)
3646 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3647 * bordering the newly created boundary use the newly computed nodes.
3649 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3650 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3652 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3653 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3655 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3656 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3658 std::vector<int> levs=getNonEmptyLevels();
3659 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3660 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3661 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3662 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3663 int nbNodes=m0->getNumberOfNodes();
3664 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3665 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3666 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3667 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3668 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3669 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3670 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3671 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3672 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3673 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3674 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3675 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3676 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3677 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3678 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3679 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3680 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3681 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3682 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3683 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3684 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3685 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3686 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3687 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3688 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3689 m0->setCoords(tmp0->getCoords());
3690 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3691 m1->setCoords(m0->getCoords());
3692 _coords=m0->getCoords(); _coords->incrRef();
3693 // duplication of cells in group 'grpNameM1' on level -1
3694 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3695 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3696 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3697 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3698 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3700 newm1->setName(getName());
3701 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3703 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !");
3704 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3705 newFam->alloc(newm1->getNumberOfCells(),1);
3706 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3707 // Positive ID for family of nodes, negative for all the rest.
3709 if (m1->getMeshDimension() == 0)
3710 idd=getMaxFamilyId()+1;
3712 idd=getMinFamilyId()-1;
3713 int globStart=0,start=0,end,globEnd;
3714 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3715 for(int i=0;i<nbOfChunks;i++)
3717 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3718 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3720 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3721 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3722 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3727 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3731 newm1->setCoords(getCoords());
3732 setMeshAtLevel(-1,newm1);
3733 setFamilyFieldArr(-1,newFam);
3734 std::string grpName2(grpNameM1); grpName2+="_dup";
3735 addFamily(grpName2,idd);
3736 addFamilyOnGrp(grpName2,grpName2);
3741 int newNbOfNodes=getCoords()->getNumberOfTuples();
3742 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3743 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3744 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3747 nodesDuplicated=nodeIdsToDuplicate.retn();
3748 cellsModified=cellsToModifyConn0.retn();
3749 cellsNotModified=cellsToModifyConn1.retn();
3753 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3754 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3755 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3757 * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering.
3758 * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered.
3760 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3762 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3763 std::vector<int> levs=getNonEmptyLevels();
3765 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3766 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3769 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3771 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3772 std::vector<int> code1=m->getDistributionOfTypes();
3773 end=PutInThirdComponentOfCodeOffset(code1,start);
3774 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3775 bool hasChanged=m->unPolyze();
3776 DataArrayInt *fake=0;
3777 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3778 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3780 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3783 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3784 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3786 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3787 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3788 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3789 setMeshAtLevel(*it,m);
3790 std::vector<int> code2=m->getDistributionOfTypes();
3791 end=PutInThirdComponentOfCodeOffset(code2,start);
3792 newCode.insert(newCode.end(),code2.begin(),code2.end());
3794 if(o2nCellsPart2->isIdentity())
3798 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3799 setFamilyFieldArr(*it,newFamField);
3803 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3804 setRenumFieldArr(*it,newNumField);
3809 newCode.insert(newCode.end(),code1.begin(),code1.end());
3815 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3816 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3817 o2nRenumCell=o2nRenumCellRet.retn();
3822 /*! \cond HIDDEN_ITEMS */
3823 struct MEDLoaderAccVisit1
3825 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3826 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3827 int _new_nb_of_nodes;
3832 * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
3833 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3834 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3835 * -1 values in returned array means that the corresponding old node is no more used.
3837 * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
3838 * is modified in \a this.
3839 * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
3842 DataArrayInt *MEDFileUMesh::zipCoords()
3844 const DataArrayDouble *coo(getCoords());
3846 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3847 int nbOfNodes(coo->getNumberOfTuples());
3848 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3849 std::vector<int> neLevs(getNonEmptyLevels());
3850 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3852 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3853 if(zeLev->isMeshStoredSplitByType())
3855 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3856 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3858 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3862 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3863 mesh->computeNodeIdsAlg(nodeIdsInUse);
3866 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3867 if(nbrOfNodesInUse==nbOfNodes)
3868 return 0;//no need to update _part_coords
3869 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3870 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3871 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3872 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3873 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3874 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3875 if((const DataArrayInt *)_fam_coords)
3876 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3877 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3878 if((const DataArrayInt *)_num_coords)
3879 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3880 if((const DataArrayAsciiChar *)_name_coords)
3881 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3882 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3883 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3885 if((MEDFileUMeshSplitL1*)*it)
3887 (*it)->renumberNodesInConn(ret->begin());
3888 (*it)->setCoords(_coords);
3891 // updates _part_coords
3892 const PartDefinition *pc(_part_coords);
3895 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3896 _part_coords=tmpPD->composeWith(pc);
3902 * This method performs an extrusion along a path defined by \a m1D.
3903 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3904 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3905 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3906 * This method scans all levels in \a this
3907 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3909 * \param [in] m1D - the mesh defining the extrusion path.
3910 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3911 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3913 * \sa MEDCouplingUMesh::buildExtrudedMesh
3915 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3917 if(getMeshDimension()!=2)
3918 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3919 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3920 m1D->checkCoherency();
3921 if(m1D->getMeshDimension()!=1)
3922 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3923 int nbRep(m1D->getNumberOfCells());
3924 std::vector<int> levs(getNonEmptyLevels());
3925 std::vector<std::string> grps(getGroupsNames());
3926 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3927 DataArrayDouble *coords(0);
3928 std::size_t nbOfLevsOut(levs.size()+1);
3929 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3930 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3932 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3933 item=item->clone(false);
3934 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3935 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3936 tmp->changeSpaceDimension(3+(*lev),0.);
3937 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3938 zeList.push_back(elt);
3940 coords=elt->getCoords();
3943 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3944 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3946 (*it)->setName(getName());
3947 (*it)->setCoords(coords);
3949 for(std::size_t ii=0;ii!=zeList.size();ii++)
3952 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
3955 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
3956 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
3957 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
3958 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
3959 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
3960 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
3961 std::vector<const MEDCouplingUMesh *> elts(3);
3962 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
3963 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
3964 elt->setName(getName());
3967 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
3968 ret->setMeshAtLevel(lev,elt);
3970 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
3971 endLev=endLev->clone(false); endLev->setCoords(coords);
3972 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
3973 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
3974 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
3975 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
3976 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
3977 endLev->setName(getName());
3978 ret->setMeshAtLevel(levs.back()-1,endLev);
3980 for(std::size_t ii=0;ii!=zeList.size();ii++)
3983 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3984 std::vector< const DataArrayInt * > outGrps2;
3987 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3989 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
3990 if(!grpArr->empty())
3992 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
3993 int offset0(zeList[ii]->getNumberOfCells());
3994 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
3995 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
3996 std::ostringstream oss; oss << grpArr2->getName() << "_top";
3997 grpArr2->setName(oss.str());
3998 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3999 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4000 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4001 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4006 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4008 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4009 if(!grpArr->empty())
4011 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4012 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
4013 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4014 for(int iii=0;iii<nbRep;iii++)
4016 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4017 grpArrs2[iii]=grpArrs[iii];
4019 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4020 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4021 std::ostringstream grpName; grpName << *grp << "_extruded";
4022 grpArrExt->setName(grpName.str());
4023 outGrps.push_back(grpArrExt);
4024 outGrps2.push_back(grpArrExt);
4027 ret->setGroupsAtLevel(lev,outGrps2);
4029 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
4030 std::vector< const DataArrayInt * > outGrps2;
4031 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4033 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4034 if(grpArr1->empty())
4036 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
4037 std::ostringstream grpName; grpName << *grp << "_top";
4038 grpArr2->setName(grpName.str());
4039 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4040 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4041 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4043 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4048 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4049 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4050 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4052 * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple
4053 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4054 * \param [in] eps - detection threshold for coordinates.
4055 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4057 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4059 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4061 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4062 int initialNbNodes(getNumberOfNodes());
4063 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4064 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4066 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4068 DataArrayDouble *zeCoords(m0->getCoords());
4069 ret->setMeshAtLevel(0,m0);
4070 std::vector<int> levs(getNonEmptyLevels());
4071 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4074 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4075 ret->setFamilyFieldArr(0,famFieldCpy);
4077 famField=getFamilyFieldAtLevel(1);
4080 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4081 fam->fillWithZero();
4082 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4083 ret->setFamilyFieldArr(1,fam);
4085 ret->copyFamGrpMapsFrom(*this);
4086 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4087 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4091 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4092 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4093 if(m1->getMeshDimension()!=0)
4096 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4097 }//kill unused notUsed var
4098 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
4100 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4101 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4104 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4105 throw INTERP_KERNEL::Exception(oss.str().c_str());
4107 b->applyLin(1,initialNbNodes);
4108 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4109 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4110 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4111 m1->renumberNodesInConn(renum->begin());
4113 m1->setCoords(zeCoords);
4114 ret->setMeshAtLevel(*lev,m1);
4115 famField=getFamilyFieldAtLevel(*lev);
4118 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4119 ret->setFamilyFieldArr(*lev,famFieldCpy);
4126 * This method converts all quadratic cells in \a this into linear cells.
4127 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4128 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4130 * \param [in] eps - detection threshold for coordinates.
4131 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4133 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4135 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4137 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4138 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4139 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4140 m0->convertQuadraticCellsToLinear();
4142 DataArrayDouble *zeCoords(m0->getCoords());
4143 ret->setMeshAtLevel(0,m0);
4144 std::vector<int> levs(getNonEmptyLevels());
4145 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4148 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4149 ret->setFamilyFieldArr(0,famFieldCpy);
4151 famField=getFamilyFieldAtLevel(1);
4154 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
4155 ret->setFamilyFieldArr(1,fam);
4157 ret->copyFamGrpMapsFrom(*this);
4158 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4162 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4163 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4164 m1->convertQuadraticCellsToLinear();
4167 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4168 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4171 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4172 throw INTERP_KERNEL::Exception(oss.str().c_str());
4174 m1->renumberNodesInConn(b->begin());
4175 m1->setCoords(zeCoords);
4176 ret->setMeshAtLevel(*lev,m1);
4177 famField=getFamilyFieldAtLevel(*lev);
4180 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4181 ret->setFamilyFieldArr(*lev,famFieldCpy);
4187 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4189 clearNonDiscrAttributes();
4190 forceComputationOfParts();
4191 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4192 std::vector<int> layer0;
4193 layer0.push_back(_order); //0 i
4194 layer0.push_back(_iteration);//1 i
4195 layer0.push_back(getSpaceDimension());//2 i
4196 tinyDouble.push_back(_time);//0 d
4197 tinyStr.push_back(_name);//0 s
4198 tinyStr.push_back(_desc_name);//1 s
4199 for(int i=0;i<getSpaceDimension();i++)
4200 tinyStr.push_back(_coords->getInfoOnComponent(i));
4201 layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
4202 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4204 tinyStr.push_back((*it).first);
4205 layer0.push_back((*it).second);
4207 layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
4208 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4210 layer0.push_back((int)(*it0).second.size());
4211 tinyStr.push_back((*it0).first);
4212 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4213 tinyStr.push_back(*it1);
4215 // sizeof(layer0)==3+aa+1+bb layer#0
4216 bigArrayD=_coords;// 0 bd
4217 bigArraysI.push_back(_fam_coords);// 0 bi
4218 bigArraysI.push_back(_num_coords);// 1 bi
4219 const PartDefinition *pd(_part_coords);
4221 layer0.push_back(-1);
4224 std::vector<int> tmp0;
4225 pd->serialize(tmp0,bigArraysI);
4226 tinyInt.push_back(tmp0.size());
4227 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4230 std::vector<int> layer1;
4231 std::vector<int> levs(getNonEmptyLevels());
4232 layer1.push_back((int)levs.size());// 0 i <- key
4233 layer1.insert(layer1.end(),levs.begin(),levs.end());
4234 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4236 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4237 lev->serialize(layer1,bigArraysI);
4239 // put layers all together.
4240 tinyInt.push_back(layer0.size());
4241 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4242 tinyInt.push_back(layer1.size());
4243 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4246 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4247 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4249 int sz0(tinyInt[0]);
4250 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4251 int sz1(tinyInt[sz0+1]);
4252 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4254 std::reverse(layer0.begin(),layer0.end());
4255 std::reverse(layer1.begin(),layer1.end());
4256 std::reverse(tinyDouble.begin(),tinyDouble.end());
4257 std::reverse(tinyStr.begin(),tinyStr.end());
4258 std::reverse(bigArraysI.begin(),bigArraysI.end());
4260 _order=layer0.back(); layer0.pop_back();
4261 _iteration=layer0.back(); layer0.pop_back();
4262 int spaceDim(layer0.back()); layer0.pop_back();
4263 _time=tinyDouble.back(); tinyDouble.pop_back();
4264 _name=tinyStr.back(); tinyStr.pop_back();
4265 _desc_name=tinyStr.back(); tinyStr.pop_back();
4266 _coords=bigArrayD; _coords->rearrange(spaceDim);
4267 for(int i=0;i<spaceDim;i++)
4269 _coords->setInfoOnComponent(i,tinyStr.back());
4272 int nbOfFams(layer0.back()); layer0.pop_back();
4274 for(int i=0;i<nbOfFams;i++)
4276 _families[tinyStr.back()]=layer0.back();
4277 tinyStr.pop_back(); layer0.pop_back();
4279 int nbGroups(layer0.back()); layer0.pop_back();
4281 for(int i=0;i<nbGroups;i++)
4283 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4284 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4285 std::vector<std::string> fams(nbOfFamsOnGrp);
4286 for(int j=0;j<nbOfFamsOnGrp;j++)
4288 fams[j]=tinyStr.back(); tinyStr.pop_back();
4290 _groups[grpName]=fams;
4292 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4293 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4295 int isPd(layer0.back()); layer0.pop_back();
4298 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4299 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4300 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4303 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4305 int nbLevs(layer1.back()); layer1.pop_back();
4306 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4308 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4309 _ms.resize(maxLev+1);
4310 for(int i=0;i<nbLevs;i++)
4314 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4319 * Adds a group of nodes to \a this mesh.
4320 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4321 * The ids should be sorted and different each other (MED file norm).
4323 * \warning this method can alter default "FAMILLE_ZERO" family.
4324 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4326 * \throw If the node coordinates array is not set.
4327 * \throw If \a ids == \c NULL.
4328 * \throw If \a ids->getName() == "".
4329 * \throw If \a ids does not respect the MED file norm.
4330 * \throw If a group with name \a ids->getName() already exists.
4332 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4334 const DataArrayDouble *coords(_coords);
4336 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4337 int nbOfNodes(coords->getNumberOfTuples());
4338 if(!((DataArrayInt *)_fam_coords))
4339 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4341 addGroupUnderground(true,ids,_fam_coords);
4345 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4347 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4348 * The ids should be sorted and different each other (MED file norm).
4350 * \warning this method can alter default "FAMILLE_ZERO" family.
4351 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4353 * \throw If the node coordinates array is not set.
4354 * \throw If \a ids == \c NULL.
4355 * \throw If \a ids->getName() == "".
4356 * \throw If \a ids does not respect the MED file norm.
4357 * \throw If a group with name \a ids->getName() already exists.
4359 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4361 std::vector<int> levs(getNonEmptyLevelsExt());
4362 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4364 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4365 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4367 if(meshDimRelToMaxExt==1)
4368 { addNodeGroup(ids); return ; }
4369 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4370 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4371 addGroupUnderground(false,ids,fam);
4375 * Changes a name of a family specified by its id.
4376 * \param [in] id - the id of the family of interest.
4377 * \param [in] newFamName - the new family name.
4378 * \throw If no family with the given \a id exists.
4380 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4382 std::string oldName=getFamilyNameGivenId(id);
4383 _families.erase(oldName);
4384 _families[newFamName]=id;
4388 * Removes a mesh of a given dimension.
4389 * \param [in] meshDimRelToMax - the relative dimension of interest.
4390 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4392 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4394 std::vector<int> levSet=getNonEmptyLevels();
4395 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4396 if(it==levSet.end())
4397 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4398 int pos=(-meshDimRelToMax);
4403 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4404 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4405 * \param [in] m - the new mesh to set.
4406 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4408 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4409 * another node coordinates array.
4410 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4411 * to the existing meshes of other levels of \a this mesh.
4413 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4415 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4416 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4420 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4421 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4422 * \param [in] m - the new mesh to set.
4423 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4424 * writing \a this mesh in a MED file.
4425 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4427 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4428 * another node coordinates array.
4429 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4430 * to the existing meshes of other levels of \a this mesh.
4432 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4434 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4435 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4438 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4440 dealWithTinyInfo(m);
4441 std::vector<int> levSet=getNonEmptyLevels();
4442 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4444 if((DataArrayDouble *)_coords==0)
4446 DataArrayDouble *c=m->getCoords();
4451 if(m->getCoords()!=_coords)
4452 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4453 int sz=(-meshDimRelToMax)+1;
4454 if(sz>=(int)_ms.size())
4456 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4460 return _ms[-meshDimRelToMax];
4464 * This method allows to set at once the content of different levels in \a this.
4465 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4467 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4468 * \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted.
4469 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4471 * \throw If \a there is a null pointer in \a ms.
4472 * \sa MEDFileUMesh::setMeshAtLevel
4474 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4478 const MEDCouplingUMesh *mRef=ms[0];
4480 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4481 std::string name(mRef->getName());
4482 const DataArrayDouble *coo(mRef->getCoords());
4485 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4487 const MEDCouplingUMesh *cur(*it);
4489 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4490 if(coo!=cur->getCoords())
4491 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4492 int mdim=cur->getMeshDimension();
4493 zeDim=std::max(zeDim,mdim);
4494 if(s.find(mdim)!=s.end())
4495 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4497 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4499 int mdim=(*it)->getMeshDimension();
4500 setName((*it)->getName());
4501 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4507 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4508 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4509 * The given meshes must share the same node coordinates array.
4510 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4511 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4512 * create in \a this mesh.
4513 * \throw If \a ms is empty.
4514 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4515 * to the existing meshes of other levels of \a this mesh.
4516 * \throw If the meshes in \a ms do not share the same node coordinates array.
4517 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4518 * of the given meshes.
4519 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4520 * \throw If names of some meshes in \a ms are equal.
4521 * \throw If \a ms includes a mesh with an empty name.
4523 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4526 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4527 int sz=(-meshDimRelToMax)+1;
4528 if(sz>=(int)_ms.size())
4530 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4531 DataArrayDouble *coo=checkMultiMesh(ms);
4532 if((DataArrayDouble *)_coords==0)
4538 if((DataArrayDouble *)_coords!=coo)
4539 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4540 std::vector<DataArrayInt *> corr;
4541 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4542 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4543 setMeshAtLevel(meshDimRelToMax,m,renum);
4544 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4545 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4549 * Creates groups at a given level in \a this mesh from a sequence of
4550 * meshes each representing a group.
4551 * The given meshes must share the same node coordinates array.
4552 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4553 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4554 * create in \a this mesh.
4555 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4557 * \throw If \a ms is empty.
4558 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4559 * to the existing meshes of other levels of \a this mesh.
4560 * \throw If the meshes in \a ms do not share the same node coordinates array.
4561 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4562 * of the given meshes.
4563 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4564 * \throw If names of some meshes in \a ms are equal.
4565 * \throw If \a ms includes a mesh with an empty name.
4567 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4570 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4571 int sz=(-meshDimRelToMax)+1;
4572 if(sz>=(int)_ms.size())
4574 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4575 DataArrayDouble *coo=checkMultiMesh(ms);
4576 if((DataArrayDouble *)_coords==0)
4582 if((DataArrayDouble *)_coords!=coo)
4583 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4584 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4585 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4587 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4589 DataArrayInt *arr=0;
4590 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4594 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4595 throw INTERP_KERNEL::Exception(oss.str().c_str());
4598 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4599 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4602 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4604 const DataArrayDouble *ret=ms[0]->getCoords();
4605 int mdim=ms[0]->getMeshDimension();
4606 for(unsigned int i=1;i<ms.size();i++)
4608 ms[i]->checkCoherency();
4609 if(ms[i]->getCoords()!=ret)
4610 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4611 if(ms[i]->getMeshDimension()!=mdim)
4612 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4614 return const_cast<DataArrayDouble *>(ret);
4618 * Sets the family field of a given relative dimension.
4619 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4620 * the family field is set.
4621 * \param [in] famArr - the array of the family field.
4622 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4623 * \throw If \a famArr has an invalid size.
4625 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4627 if(meshDimRelToMaxExt==1)
4634 DataArrayDouble *coo(_coords);
4636 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4637 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4642 if(meshDimRelToMaxExt>1)
4643 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4644 int traducedRk=-meshDimRelToMaxExt;
4645 if(traducedRk>=(int)_ms.size())
4646 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4647 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4648 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4649 return _ms[traducedRk]->setFamilyArr(famArr);
4653 * Sets the optional numbers of mesh entities of a given dimension.
4654 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4655 * \param [in] renumArr - the array of the numbers.
4656 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4657 * \throw If \a renumArr has an invalid size.
4659 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4661 if(meshDimRelToMaxExt==1)
4669 DataArrayDouble *coo(_coords);
4671 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4672 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4673 renumArr->incrRef();
4674 _num_coords=renumArr;
4678 if(meshDimRelToMaxExt>1)
4679 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4680 int traducedRk=-meshDimRelToMaxExt;
4681 if(traducedRk>=(int)_ms.size())
4682 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4683 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4684 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4685 return _ms[traducedRk]->setRenumArr(renumArr);
4689 * Sets the optional names of mesh entities of a given dimension.
4690 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4691 * \param [in] nameArr - the array of the names.
4692 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4693 * \throw If \a nameArr has an invalid size.
4695 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4697 if(meshDimRelToMaxExt==1)
4704 DataArrayDouble *coo(_coords);
4706 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4707 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4709 _name_coords=nameArr;
4712 if(meshDimRelToMaxExt>1)
4713 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4714 int traducedRk=-meshDimRelToMaxExt;
4715 if(traducedRk>=(int)_ms.size())
4716 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4717 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4718 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4719 return _ms[traducedRk]->setNameArr(nameArr);
4722 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4724 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4725 if((const MEDFileUMeshSplitL1 *)(*it))
4726 (*it)->synchronizeTinyInfo(*this);
4730 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4732 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4734 DataArrayInt *arr=_fam_coords;
4736 arr->changeValue(oldId,newId);
4737 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4739 MEDFileUMeshSplitL1 *sp=(*it);
4742 sp->changeFamilyIdArr(oldId,newId);
4747 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4749 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4750 const DataArrayInt *da(_fam_coords);
4752 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4753 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4755 const MEDFileUMeshSplitL1 *elt(*it);
4758 da=elt->getFamilyField();
4760 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4766 void MEDFileUMesh::computeRevNum() const
4768 if((const DataArrayInt *)_num_coords)
4771 int maxValue=_num_coords->getMaxValue(pos);
4772 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4776 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4778 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4781 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4783 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4784 ret.push_back((const DataArrayInt *)_fam_nodes);
4785 ret.push_back((const DataArrayInt *)_num_nodes);
4786 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4787 ret.push_back((const DataArrayInt *)_fam_cells);
4788 ret.push_back((const DataArrayInt *)_num_cells);
4789 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4790 ret.push_back((const DataArrayInt *)_fam_faces);
4791 ret.push_back((const DataArrayInt *)_num_faces);
4792 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4793 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4794 ret.push_back((const DataArrayInt *)_rev_num_cells);
4795 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4799 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4801 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4802 if((const DataArrayInt *)_fam_nodes)
4804 int val=_fam_nodes->getMaxValue(tmp);
4805 ret=std::max(ret,std::abs(val));
4807 if((const DataArrayInt *)_fam_cells)
4809 int val=_fam_cells->getMaxValue(tmp);
4810 ret=std::max(ret,std::abs(val));
4812 if((const DataArrayInt *)_fam_faces)
4814 int val=_fam_faces->getMaxValue(tmp);
4815 ret=std::max(ret,std::abs(val));
4820 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4822 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4823 if((const DataArrayInt *)_fam_nodes)
4825 int val=_fam_nodes->getMaxValue(tmp);
4826 ret=std::max(ret,val);
4828 if((const DataArrayInt *)_fam_cells)
4830 int val=_fam_cells->getMaxValue(tmp);
4831 ret=std::max(ret,val);
4833 if((const DataArrayInt *)_fam_faces)
4835 int val=_fam_faces->getMaxValue(tmp);
4836 ret=std::max(ret,val);
4841 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4843 int ret=std::numeric_limits<int>::max(),tmp=-1;
4844 if((const DataArrayInt *)_fam_nodes)
4846 int val=_fam_nodes->getMinValue(tmp);
4847 ret=std::min(ret,val);
4849 if((const DataArrayInt *)_fam_cells)
4851 int val=_fam_cells->getMinValue(tmp);
4852 ret=std::min(ret,val);
4854 if((const DataArrayInt *)_fam_faces)
4856 int val=_fam_faces->getMinValue(tmp);
4857 ret=std::min(ret,val);
4862 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4864 if(!MEDFileMesh::isEqual(other,eps,what))
4866 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4869 what="Mesh types differ ! This is structured and other is NOT !";
4872 const DataArrayInt *famc1=_fam_nodes;
4873 const DataArrayInt *famc2=otherC->_fam_nodes;
4874 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4876 what="Mismatch of families arr on nodes ! One is defined and not other !";
4881 bool ret=famc1->isEqual(*famc2);
4884 what="Families arr on nodes differ !";
4889 famc2=otherC->_fam_cells;
4890 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4892 what="Mismatch of families arr on cells ! One is defined and not other !";
4897 bool ret=famc1->isEqual(*famc2);
4900 what="Families arr on cells differ !";
4905 famc2=otherC->_fam_faces;
4906 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4908 what="Mismatch of families arr on faces ! One is defined and not other !";
4913 bool ret=famc1->isEqual(*famc2);
4916 what="Families arr on faces differ !";
4921 famc2=otherC->_num_nodes;
4922 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4924 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4929 bool ret=famc1->isEqual(*famc2);
4932 what="Numbering arr on nodes differ !";
4937 famc2=otherC->_num_cells;
4938 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4940 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4945 bool ret=famc1->isEqual(*famc2);
4948 what="Numbering arr on cells differ !";
4953 famc2=otherC->_num_faces;
4954 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4956 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4961 bool ret=famc1->isEqual(*famc2);
4964 what="Numbering arr on faces differ !";
4968 const DataArrayAsciiChar *d1=_names_cells;
4969 const DataArrayAsciiChar *d2=otherC->_names_cells;
4970 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4972 what="Mismatch of naming arr on cells ! One is defined and not other !";
4977 bool ret=d1->isEqual(*d2);
4980 what="Naming arr on cells differ !";
4985 d2=otherC->_names_faces;
4986 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4988 what="Mismatch of naming arr on faces ! One is defined and not other !";
4993 bool ret=d1->isEqual(*d2);
4996 what="Naming arr on faces differ !";
5001 d2=otherC->_names_nodes;
5002 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5004 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5009 bool ret=d1->isEqual(*d2);
5012 what="Naming arr on nodes differ !";
5019 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5021 MEDFileMesh::clearNonDiscrAttributes();
5022 const DataArrayInt *tmp=_fam_nodes;
5024 (const_cast<DataArrayInt *>(tmp))->setName("");
5027 (const_cast<DataArrayInt *>(tmp))->setName("");
5030 (const_cast<DataArrayInt *>(tmp))->setName("");
5033 (const_cast<DataArrayInt *>(tmp))->setName("");
5036 (const_cast<DataArrayInt *>(tmp))->setName("");
5039 (const_cast<DataArrayInt *>(tmp))->setName("");
5043 * Returns ids of mesh entities contained in given families of a given dimension.
5044 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5046 * \param [in] fams - the names of the families of interest.
5047 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5048 * returned instead of ids.
5049 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5050 * numbers, if available and required, of mesh entities of the families. The caller
5051 * is to delete this array using decrRef() as it is no more needed.
5052 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5054 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5056 std::vector<int> famIds(getFamiliesIds(fams));
5057 switch(meshDimRelToMaxExt)
5061 if((const DataArrayInt *)_fam_nodes)
5063 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5065 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5067 da=_fam_nodes->getIdsEqualList(0,0);
5069 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5074 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5079 if((const DataArrayInt *)_fam_cells)
5081 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5083 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5085 da=_fam_cells->getIdsEqualList(0,0);
5087 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5092 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5097 if((const DataArrayInt *)_fam_faces)
5099 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5101 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5103 da=_fam_faces->getIdsEqualList(0,0);
5105 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5110 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5114 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5116 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5120 * Sets the family field of a given relative dimension.
5121 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5122 * the family field is set.
5123 * \param [in] famArr - the array of the family field.
5124 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5125 * \throw If \a famArr has an invalid size.
5126 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5128 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5130 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5132 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5133 switch(meshDimRelToMaxExt)
5137 int nbCells=mesh->getNumberOfCells();
5138 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5144 int nbNodes=mesh->getNumberOfNodes();
5145 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5151 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5152 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5157 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5164 * Sets the optional numbers of mesh entities of a given dimension.
5165 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5166 * \param [in] renumArr - the array of the numbers.
5167 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5168 * \throw If \a renumArr has an invalid size.
5169 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5171 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5173 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5175 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5176 switch(meshDimRelToMaxExt)
5180 int nbCells=mesh->getNumberOfCells();
5181 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5182 _num_cells=renumArr;
5187 int nbNodes=mesh->getNumberOfNodes();
5188 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5189 _num_nodes=renumArr;
5194 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5195 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5196 _num_faces=renumArr;
5200 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5203 renumArr->incrRef();
5207 * Sets the optional names of mesh entities of a given dimension.
5208 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5209 * \param [in] nameArr - the array of the names.
5210 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5211 * \throw If \a nameArr has an invalid size.
5213 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5215 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5217 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5218 switch(meshDimRelToMaxExt)
5222 int nbCells=mesh->getNumberOfCells();
5223 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5224 _names_cells=nameArr;
5229 int nbNodes=mesh->getNumberOfNodes();
5230 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5231 _names_nodes=nameArr;
5236 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5237 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5238 _names_cells=nameArr;
5241 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5248 * Adds a group of nodes to \a this mesh.
5249 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5250 * The ids should be sorted and different each other (MED file norm).
5252 * \warning this method can alter default "FAMILLE_ZERO" family.
5253 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5255 * \throw If the node coordinates array is not set.
5256 * \throw If \a ids == \c NULL.
5257 * \throw If \a ids->getName() == "".
5258 * \throw If \a ids does not respect the MED file norm.
5259 * \throw If a group with name \a ids->getName() already exists.
5261 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5267 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5269 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5270 * The ids should be sorted and different each other (MED file norm).
5272 * \warning this method can alter default "FAMILLE_ZERO" family.
5273 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5275 * \throw If the node coordinates array is not set.
5276 * \throw If \a ids == \c NULL.
5277 * \throw If \a ids->getName() == "".
5278 * \throw If \a ids does not respect the MED file norm.
5279 * \throw If a group with name \a ids->getName() already exists.
5281 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5283 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5284 addGroupUnderground(false,ids,fam);
5289 * Returns the family field for mesh entities of a given dimension.
5290 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5291 * \return const DataArrayInt * - the family field. It is an array of ids of families
5292 * each mesh entity belongs to. It can be \c NULL.
5293 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5295 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5297 switch(meshDimRelToMaxExt)
5306 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5311 * Returns the family field for mesh entities of a given dimension.
5312 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5313 * \return const DataArrayInt * - the family field. It is an array of ids of families
5314 * each mesh entity belongs to. It can be \c NULL.
5315 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5317 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5319 switch(meshDimRelToMaxExt)
5328 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5333 * Returns the optional numbers of mesh entities of a given dimension.
5334 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5335 * \return const DataArrayInt * - the array of the entity numbers.
5336 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5337 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5339 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5341 switch(meshDimRelToMaxExt)
5350 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5355 * Returns the optional numbers of mesh entities of a given dimension transformed using
5356 * DataArrayInt::invertArrayN2O2O2N().
5357 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5358 * \return const DataArrayInt * - the array of the entity numbers transformed using
5359 * DataArrayInt::invertArrayN2O2O2N().
5360 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5361 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5363 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5365 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5366 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5367 if(meshDimRelToMaxExt==0)
5369 if((const DataArrayInt *)_num_cells)
5372 int maxValue=_num_cells->getMaxValue(pos);
5373 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5374 return _rev_num_cells;
5377 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5381 if((const DataArrayInt *)_num_nodes)
5384 int maxValue=_num_nodes->getMaxValue(pos);
5385 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5386 return _rev_num_nodes;
5389 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5393 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5395 switch(meshDimRelToMaxExt)
5398 return _names_cells;
5400 return _names_nodes;
5402 return _names_faces;
5404 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5409 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5410 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5412 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5414 std::vector<int> ret(1);
5419 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5420 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5422 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5424 std::vector<int> ret(2);
5430 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5432 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5434 std::vector<int> ret;
5435 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5446 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5448 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5450 std::vector<int> ret;
5451 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5462 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5464 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5466 std::vector<int> ret;
5467 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5478 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5480 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5482 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5486 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5488 DataArrayInt *arr=_fam_nodes;
5490 arr->changeValue(oldId,newId);
5493 arr->changeValue(oldId,newId);
5496 arr->changeValue(oldId,newId);
5499 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5501 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
5502 const DataArrayInt *da(_fam_nodes);
5504 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5507 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5510 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5514 void MEDFileStructuredMesh::deepCpyAttributes()
5516 if((const DataArrayInt*)_fam_nodes)
5517 _fam_nodes=_fam_nodes->deepCpy();
5518 if((const DataArrayInt*)_num_nodes)
5519 _num_nodes=_num_nodes->deepCpy();
5520 if((const DataArrayAsciiChar*)_names_nodes)
5521 _names_nodes=_names_nodes->deepCpy();
5522 if((const DataArrayInt*)_fam_cells)
5523 _fam_cells=_fam_cells->deepCpy();
5524 if((const DataArrayInt*)_num_cells)
5525 _num_cells=_num_cells->deepCpy();
5526 if((const DataArrayAsciiChar*)_names_cells)
5527 _names_cells=_names_cells->deepCpy();
5528 if((const DataArrayInt*)_fam_faces)
5529 _fam_faces=_fam_faces->deepCpy();
5530 if((const DataArrayInt*)_num_faces)
5531 _num_faces=_num_faces->deepCpy();
5532 if((const DataArrayAsciiChar*)_names_faces)
5533 _names_faces=_names_faces->deepCpy();
5534 if((const DataArrayInt*)_rev_num_nodes)
5535 _rev_num_nodes=_rev_num_nodes->deepCpy();
5536 if((const DataArrayInt*)_rev_num_cells)
5537 _rev_num_cells=_rev_num_cells->deepCpy();
5541 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5543 * \return a pointer to cartesian mesh that need to be managed by the caller.
5544 * \warning the returned pointer has to be managed by the caller.
5548 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5549 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5550 * \param [in] renum - it must be \c false.
5551 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5552 * delete using decrRef() as it is no more needed.
5554 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
5557 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5558 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5559 switch(meshDimRelToMax)
5565 return const_cast<MEDCouplingStructuredMesh *>(m);
5570 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5571 buildMinusOneImplicitPartIfNeeded();
5572 MEDCouplingMesh *ret(_faces_if_necessary);
5578 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5583 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5584 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5585 * \return int - the number of entities.
5586 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5588 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5590 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5592 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5593 switch(meshDimRelToMaxExt)
5596 return cmesh->getNumberOfCells();
5598 return cmesh->getNumberOfNodes();
5600 return cmesh->getNumberOfCellsOfSubLevelMesh();
5602 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5606 int MEDFileStructuredMesh::getNumberOfNodes() const
5608 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5610 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5611 return cmesh->getNumberOfNodes();
5614 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5616 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5618 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5619 switch(meshDimRelToMaxExt)
5622 return cmesh->getNumberOfCells();
5624 return cmesh->getNumberOfCellsOfSubLevelMesh();
5626 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5630 bool MEDFileStructuredMesh::hasImplicitPart() const
5636 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5638 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5640 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5641 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5644 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5645 if(cm.getReverseExtrudedType()!=gt)
5646 throw INTERP_KERNEL::Exception(MSG);
5647 buildImplicitPart();
5648 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5652 if(gt!=zeFaceMesh->getCellModelEnum())
5653 throw INTERP_KERNEL::Exception(MSG);
5654 return zeFaceMesh->getNumberOfCells();
5658 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5660 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5662 buildImplicitPart();
5665 void MEDFileStructuredMesh::buildImplicitPart() const
5667 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5669 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5670 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5673 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5675 _faces_if_necessary=0;
5679 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5680 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5682 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5684 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5686 return _faces_if_necessary;
5689 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5691 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5693 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5694 switch(meshDimRelToMax)
5698 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5703 int mdim(cmesh->getMeshDimension());
5705 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5706 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5710 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5714 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
5716 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5719 return getNumberOfCellsAtLevel(0);
5722 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5724 if(st.getNumberOfItems()!=1)
5725 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !");
5726 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5727 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5728 if(getNumberOfNodes()!=(int)nodesFetched.size())
5729 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5730 if(st[0].getPflName().empty())
5732 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5735 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5736 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5737 int sz(nodesFetched.size());
5738 for(const int *work=arr->begin();work!=arr->end();work++)
5740 std::vector<int> conn;
5741 cmesh->getNodeIdsOfCell(*work,conn);
5742 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5743 if(*it>=0 && *it<sz)
5744 nodesFetched[*it]=true;
5746 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5750 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5752 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5756 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5757 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5759 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5760 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5762 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5765 if(!mrs || mrs->isCellFamilyFieldReading())
5767 famCells=DataArrayInt::New();
5768 famCells->alloc(nbOfElt,1);
5769 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
5772 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5775 if(!mrs || mrs->isCellNumFieldReading())
5777 numCells=DataArrayInt::New();
5778 numCells->alloc(nbOfElt,1);
5779 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
5782 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5785 if(!mrs || mrs->isCellNameFieldReading())
5787 namesCells=DataArrayAsciiChar::New();
5788 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5789 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
5790 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5795 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5797 setName(strm->getName());
5798 setDescription(strm->getDescription());
5799 setUnivName(strm->getUnivName());
5800 setIteration(strm->getIteration());
5801 setOrder(strm->getOrder());
5802 setTimeValue(strm->getTime());
5803 setTimeUnit(strm->getTimeUnit());
5804 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5805 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5806 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
5809 if(!mrs || mrs->isNodeFamilyFieldReading())
5811 int nbNodes(getNumberOfNodes());
5813 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5814 _fam_nodes=DataArrayInt::New();
5815 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5816 if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378...
5817 _fam_nodes->fillWithZero();
5818 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
5821 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5824 if(!mrs || mrs->isNodeNumFieldReading())
5826 _num_nodes=DataArrayInt::New();
5827 _num_nodes->alloc(nbOfElt,1);
5828 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
5831 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5834 if(!mrs || mrs->isNodeNameFieldReading())
5836 _names_nodes=DataArrayAsciiChar::New();
5837 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5838 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
5839 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5842 int meshDim(getStructuredMesh()->getMeshDimension());
5843 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5845 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5848 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5850 int meshDim(getStructuredMesh()->getMeshDimension());
5851 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5853 if((const DataArrayInt *)_fam_cells)
5854 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
5855 if((const DataArrayInt *)_fam_faces)
5856 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
5857 if((const DataArrayInt *)_fam_nodes)
5858 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
5859 if((const DataArrayInt *)_num_cells)
5860 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
5861 if((const DataArrayInt *)_num_faces)
5862 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
5863 if((const DataArrayInt *)_num_nodes)
5864 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
5865 if((const DataArrayAsciiChar *)_names_cells)
5867 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5869 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5870 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5871 throw INTERP_KERNEL::Exception(oss.str().c_str());
5873 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
5875 if((const DataArrayAsciiChar *)_names_faces)
5877 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5879 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5880 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5881 throw INTERP_KERNEL::Exception(oss.str().c_str());
5883 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
5885 if((const DataArrayAsciiChar *)_names_nodes)
5887 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5889 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5890 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5891 throw INTERP_KERNEL::Exception(oss.str().c_str());
5893 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
5896 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5900 * Returns an empty instance of MEDFileCMesh.
5901 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5902 * mesh using decrRef() as it is no more needed.
5904 MEDFileCMesh *MEDFileCMesh::New()
5906 return new MEDFileCMesh;
5910 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5911 * file. The first mesh in the file is loaded.
5912 * \param [in] fileName - the name of MED file to read.
5913 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5914 * mesh using decrRef() as it is no more needed.
5915 * \throw If the file is not readable.
5916 * \throw If there is no meshes in the file.
5917 * \throw If the mesh in the file is not a Cartesian one.
5919 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5921 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5924 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5925 throw INTERP_KERNEL::Exception(oss.str().c_str());
5927 MEDFileUtilities::CheckFileForRead(fileName);
5928 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5930 ParaMEDMEM::MEDCouplingMeshType meshType;
5932 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5933 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5937 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5938 * file. The mesh to load is specified by its name and numbers of a time step and an
5940 * \param [in] fileName - the name of MED file to read.
5941 * \param [in] mName - the name of the mesh to read.
5942 * \param [in] dt - the number of a time step.
5943 * \param [in] it - the number of an iteration.
5944 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5945 * mesh using decrRef() as it is no more needed.
5946 * \throw If the file is not readable.
5947 * \throw If there is no mesh with given attributes in the file.
5948 * \throw If the mesh in the file is not a Cartesian one.
5950 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5952 MEDFileUtilities::CheckFileForRead(fileName);
5953 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5954 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5957 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5959 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5962 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5964 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5965 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5970 * Returns the dimension on cells in \a this mesh.
5971 * \return int - the mesh dimension.
5972 * \throw If there are no cells in this mesh.
5974 int MEDFileCMesh::getMeshDimension() const
5976 if(!((const MEDCouplingCMesh*)_cmesh))
5977 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5978 return _cmesh->getMeshDimension();
5982 * Returns the dimension on nodes in \a this mesh.
5983 * \return int - the space dimension.
5984 * \throw If there are no cells in this mesh.
5986 int MEDFileCMesh::getSpaceDimension() const
5988 if(!((const MEDCouplingCMesh*)_cmesh))
5989 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5990 return _cmesh->getSpaceDimension();
5994 * Returns a string describing \a this mesh.
5995 * \return std::string - the mesh information string.
5997 std::string MEDFileCMesh::simpleRepr() const
5999 return MEDFileStructuredMesh::simpleRepr();
6003 * Returns a full textual description of \a this mesh.
6004 * \return std::string - the string holding the mesh description.
6006 std::string MEDFileCMesh::advancedRepr() const
6008 return simpleRepr();
6011 MEDFileMesh *MEDFileCMesh::shallowCpy() const
6013 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
6017 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6019 return new MEDFileCMesh;
6022 MEDFileMesh *MEDFileCMesh::deepCpy() const
6024 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
6025 ret->deepCpyEquivalences(*this);
6026 if((const MEDCouplingCMesh*)_cmesh)
6027 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
6028 ret->deepCpyAttributes();
6033 * Checks if \a this and another mesh are equal.
6034 * \param [in] other - the mesh to compare with.
6035 * \param [in] eps - a precision used to compare real values.
6036 * \param [in,out] what - the string returning description of unequal data.
6037 * \return bool - \c true if the meshes are equal, \c false, else.
6039 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6041 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6043 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6046 what="Mesh types differ ! This is cartesian and other is NOT !";
6049 clearNonDiscrAttributes();
6050 otherC->clearNonDiscrAttributes();
6051 const MEDCouplingCMesh *coo1=_cmesh;
6052 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6053 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6055 what="Mismatch of cartesian meshes ! One is defined and not other !";
6060 bool ret=coo1->isEqual(coo2,eps);
6063 what="cartesian meshes differ !";
6071 * Clears redundant attributes of incorporated data arrays.
6073 void MEDFileCMesh::clearNonDiscrAttributes() const
6075 MEDFileStructuredMesh::clearNonDiscrAttributes();
6076 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6079 MEDFileCMesh::MEDFileCMesh()
6083 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6086 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6088 catch(INTERP_KERNEL::Exception& e)
6093 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6095 ParaMEDMEM::MEDCouplingMeshType meshType;
6098 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6099 if(meshType!=CARTESIAN)
6101 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6102 throw INTERP_KERNEL::Exception(oss.str().c_str());
6104 MEDFileCMeshL2 loaderl2;
6105 loaderl2.loadAll(fid,mid,mName,dt,it);
6106 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6109 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6113 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6114 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6116 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6118 synchronizeTinyInfoOnLeaves();
6122 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6124 synchronizeTinyInfoOnLeaves();
6129 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6130 * \param [in] m - the new MEDCouplingCMesh to refer to.
6131 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6134 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6136 dealWithTinyInfo(m);
6142 void MEDFileCMesh::writeLL(med_idt fid) const
6144 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6145 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6146 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6147 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6148 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6149 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6150 int spaceDim(_cmesh->getSpaceDimension());
6151 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6152 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6153 for(int i=0;i<spaceDim;i++)
6155 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6157 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6158 MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
6159 MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
6161 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
6163 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6164 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID));
6165 for(int i=0;i<spaceDim;i++)
6167 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6168 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6171 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6172 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6175 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6177 const MEDCouplingCMesh *cmesh=_cmesh;
6180 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6181 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6182 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6183 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6186 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6188 return new MEDFileCurveLinearMesh;
6191 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6193 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6196 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6197 throw INTERP_KERNEL::Exception(oss.str().c_str());
6199 MEDFileUtilities::CheckFileForRead(fileName);
6200 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6202 ParaMEDMEM::MEDCouplingMeshType meshType;
6204 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6205 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6208 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6210 MEDFileUtilities::CheckFileForRead(fileName);
6211 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6212 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6215 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6217 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6220 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6222 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6223 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6227 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6229 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6233 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6235 return new MEDFileCurveLinearMesh;
6238 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
6240 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6241 ret->deepCpyEquivalences(*this);
6242 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6243 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
6244 ret->deepCpyAttributes();
6248 int MEDFileCurveLinearMesh::getMeshDimension() const
6250 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6251 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6252 return _clmesh->getMeshDimension();
6255 std::string MEDFileCurveLinearMesh::simpleRepr() const
6257 return MEDFileStructuredMesh::simpleRepr();
6260 std::string MEDFileCurveLinearMesh::advancedRepr() const
6262 return simpleRepr();
6265 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6267 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6269 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6272 what="Mesh types differ ! This is curve linear and other is NOT !";
6275 clearNonDiscrAttributes();
6276 otherC->clearNonDiscrAttributes();
6277 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6278 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6279 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6281 what="Mismatch of curve linear meshes ! One is defined and not other !";
6286 bool ret=coo1->isEqual(coo2,eps);
6289 what="curve linear meshes differ !";
6296 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6298 MEDFileStructuredMesh::clearNonDiscrAttributes();
6299 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6302 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6304 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6307 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6308 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6309 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6310 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6313 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6315 synchronizeTinyInfoOnLeaves();
6319 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6321 dealWithTinyInfo(m);
6327 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6329 synchronizeTinyInfoOnLeaves();
6333 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6337 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6340 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6342 catch(INTERP_KERNEL::Exception& e)
6347 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6349 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6350 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6351 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6352 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6353 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6354 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6355 int spaceDim=_clmesh->getSpaceDimension();
6356 int meshDim=_clmesh->getMeshDimension();
6357 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6358 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6359 const DataArrayDouble *coords=_clmesh->getCoords();
6361 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6362 for(int i=0;i<spaceDim;i++)
6364 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6366 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6367 MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
6368 MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
6370 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
6372 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6373 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6374 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6375 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6377 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6379 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6380 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6383 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6385 ParaMEDMEM::MEDCouplingMeshType meshType;
6388 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6389 if(meshType!=CURVE_LINEAR)
6391 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6392 throw INTERP_KERNEL::Exception(oss.str().c_str());
6394 MEDFileCLMeshL2 loaderl2;
6395 loaderl2.loadAll(fid,mid,mName,dt,it);
6396 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6399 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6402 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6404 return new MEDFileMeshMultiTS;
6407 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6409 return new MEDFileMeshMultiTS(fileName);
6412 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6414 return new MEDFileMeshMultiTS(fileName,mName);
6417 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6419 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6420 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6422 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6423 if((const MEDFileMesh *)*it)
6424 meshOneTs[i]=(*it)->deepCpy();
6425 ret->_mesh_one_ts=meshOneTs;
6429 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6431 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6434 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6436 std::vector<const BigMemoryObject *> ret;
6437 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6438 ret.push_back((const MEDFileMesh *)*it);
6442 std::string MEDFileMeshMultiTS::getName() const
6444 if(_mesh_one_ts.empty())
6445 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6446 return _mesh_one_ts[0]->getName();
6449 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6451 std::string oldName(getName());
6452 std::vector< std::pair<std::string,std::string> > v(1);
6453 v[0].first=oldName; v[0].second=newMeshName;
6457 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6460 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6462 MEDFileMesh *cur(*it);
6464 ret=cur->changeNames(modifTab) || ret;
6469 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6471 if(_mesh_one_ts.empty())
6472 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6473 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6476 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6479 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6480 _mesh_one_ts.resize(1);
6481 mesh1TimeStep->incrRef();
6482 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6483 _mesh_one_ts[0]=mesh1TimeStep;
6486 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
6488 if ( MEDFileMesh* m = getOneTimeStep() )
6489 return m->getJoints();
6494 * \brief Set Joints that are common to all time-stamps
6496 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
6498 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6500 (*it)->setJoints( joints );
6504 void MEDFileMeshMultiTS::write(med_idt fid) const
6506 MEDFileJoints *joints(getJoints());
6507 bool jointsWritten(false);
6509 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6511 if ( jointsWritten )
6512 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
6514 jointsWritten = true;
6516 (*it)->copyOptionsFrom(*this);
6520 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
6523 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6525 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6526 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6527 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6528 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6532 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6534 MEDFileJoints* joints = 0;
6535 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
6537 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
6538 joints = getOneTimeStep()->getJoints();
6541 _mesh_one_ts.clear(); //for the moment to be improved
6542 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
6545 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6549 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6552 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6555 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6556 throw INTERP_KERNEL::Exception(oss.str().c_str());
6558 MEDFileUtilities::CheckFileForRead(fileName);
6559 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6561 ParaMEDMEM::MEDCouplingMeshType meshType;
6563 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6564 loadFromFile(fileName,ms.front());
6566 catch(INTERP_KERNEL::Exception& e)
6571 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6574 loadFromFile(fileName,mName);
6576 catch(INTERP_KERNEL::Exception& e)
6581 MEDFileMeshes *MEDFileMeshes::New()
6583 return new MEDFileMeshes;
6586 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6588 return new MEDFileMeshes(fileName);
6591 void MEDFileMeshes::write(med_idt fid) const
6594 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6596 (*it)->copyOptionsFrom(*this);
6601 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6603 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6604 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6605 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6606 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6611 int MEDFileMeshes::getNumberOfMeshes() const
6613 return _meshes.size();
6616 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6618 return new MEDFileMeshesIterator(this);
6621 /** Return a borrowed reference (caller is not responsible) */
6622 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6624 if(i<0 || i>=(int)_meshes.size())
6626 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6627 throw INTERP_KERNEL::Exception(oss.str().c_str());
6629 return _meshes[i]->getOneTimeStep();
6632 /** Return a borrowed reference (caller is not responsible) */
6633 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6635 std::vector<std::string> ms=getMeshesNames();
6636 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6639 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6640 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6641 throw INTERP_KERNEL::Exception(oss.str().c_str());
6643 return getMeshAtPos((int)std::distance(ms.begin(),it));
6646 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6648 std::vector<std::string> ret(_meshes.size());
6650 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6652 const MEDFileMeshMultiTS *f=(*it);
6655 ret[i]=f->getName();
6659 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6660 throw INTERP_KERNEL::Exception(oss.str().c_str());
6665 /*const MEDFileJoints* MEDFileMeshes::getJoints() const
6667 const MEDFileJoints *ret=_joints;
6670 std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !";
6671 throw INTERP_KERNEL::Exception(oss.str().c_str());
6676 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6679 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6681 MEDFileMeshMultiTS *cur(*it);
6683 ret=cur->changeNames(modifTab) || ret;
6688 void MEDFileMeshes::resize(int newSize)
6690 _meshes.resize(newSize);
6693 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6696 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6697 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6698 elt->setOneTimeStep(mesh);
6699 _meshes.push_back(elt);
6702 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6705 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6706 if(i>=(int)_meshes.size())
6707 _meshes.resize(i+1);
6708 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6709 elt->setOneTimeStep(mesh);
6713 void MEDFileMeshes::destroyMeshAtPos(int i)
6715 if(i<0 || i>=(int)_meshes.size())
6717 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6718 throw INTERP_KERNEL::Exception(oss.str().c_str());
6720 _meshes.erase(_meshes.begin()+i);
6723 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6725 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6727 _meshes.resize(ms.size());
6728 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6729 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6732 MEDFileMeshes::MEDFileMeshes()
6736 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6739 loadFromFile(fileName);
6741 catch(INTERP_KERNEL::Exception& /*e*/)
6745 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6747 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6749 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6750 if((const MEDFileMeshMultiTS *)*it)
6751 meshes[i]=(*it)->deepCpy();
6752 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6753 ret->_meshes=meshes;
6757 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6759 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6762 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6764 std::vector<const BigMemoryObject *> ret;
6765 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6766 ret.push_back((const MEDFileMeshMultiTS *)*it);
6770 std::string MEDFileMeshes::simpleRepr() const
6772 std::ostringstream oss;
6773 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6774 simpleReprWithoutHeader(oss);
6778 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6780 int nbOfMeshes=getNumberOfMeshes();
6781 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6782 std::vector<std::string> mns=getMeshesNames();
6783 for(int i=0;i<nbOfMeshes;i++)
6784 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6787 void MEDFileMeshes::checkCoherency() const
6789 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6791 std::set<std::string> s;
6792 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6794 const MEDFileMeshMultiTS *elt=(*it);
6797 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6798 throw INTERP_KERNEL::Exception(oss.str().c_str());
6800 std::size_t sz=s.size();
6801 s.insert(std::string((*it)->getName()));
6804 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6805 throw INTERP_KERNEL::Exception(oss.str().c_str());
6810 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6815 _nb_iter=ms->getNumberOfMeshes();
6819 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6823 MEDFileMesh *MEDFileMeshesIterator::nextt()
6825 if(_iter_id<_nb_iter)
6827 MEDFileMeshes *ms(_ms);
6829 return ms->getMeshAtPos(_iter_id++);