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 * Returns names of all families of \a this mesh but like they would be in file.
518 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
519 * This method is only useful for aggressive users that want to have in their file a same family lying both on cells and on nodes. This is not a good idea for lisibility !
520 * For your information internaly in memory such families are renamed to have a nicer API.
522 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
524 std::vector<std::string> ret(getFamiliesNames());
525 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
529 std::string MEDFileMesh::GetMagicFamilyStr()
531 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
535 * Changes a name of every family, included in one group only, to be same as the group name.
536 * \throw If there are families with equal names in \a this mesh.
538 void MEDFileMesh::assignFamilyNameWithGroupName()
540 std::map<std::string, std::vector<std::string> > groups(_groups);
541 std::map<std::string,int> newFams;
542 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
544 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
545 if(grps.size()==1 && groups[grps[0]].size()==1)
547 if(newFams.find(grps[0])!=newFams.end())
549 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
550 throw INTERP_KERNEL::Exception(oss.str().c_str());
552 newFams[grps[0]]=(*it).second;
553 std::vector<std::string>& grps2=groups[grps[0]];
554 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
559 if(newFams.find((*it).first)!=newFams.end())
561 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
562 throw INTERP_KERNEL::Exception(oss.str().c_str());
564 newFams[(*it).first]=(*it).second;
572 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
574 * \return the removed groups.
576 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
578 std::vector<std::string> ret;
579 std::map<std::string, std::vector<std::string> > newGrps;
580 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
582 if((*it).second.empty())
583 ret.push_back((*it).first);
585 newGrps[(*it).first]=(*it).second;
593 * Removes a group from \a this mesh.
594 * \param [in] name - the name of the group to remove.
595 * \throw If no group with such a \a name exists.
597 void MEDFileMesh::removeGroup(const std::string& name)
599 std::string oname(name);
600 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
601 std::vector<std::string> grps=getGroupsNames();
602 if(it==_groups.end())
604 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
605 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
606 throw INTERP_KERNEL::Exception(oss.str().c_str());
612 * Removes a family from \a this mesh.
613 * \param [in] name - the name of the family to remove.
614 * \throw If no family with such a \a name exists.
616 void MEDFileMesh::removeFamily(const std::string& name)
618 std::string oname(name);
619 std::map<std::string, int >::iterator it=_families.find(oname);
620 std::vector<std::string> fams=getFamiliesNames();
621 if(it==_families.end())
623 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
624 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
625 throw INTERP_KERNEL::Exception(oss.str().c_str());
628 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
630 std::vector<std::string>& v=(*it3).second;
631 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
638 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
639 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
640 * family field whatever its level. This method also suppresses the orphan families.
642 * \return - The list of removed groups names.
644 * \sa MEDFileMesh::removeOrphanFamilies.
646 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
648 removeOrphanFamilies();
649 return removeEmptyGroups();
653 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
654 * 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.
656 * \return - The list of removed families names.
657 * \sa MEDFileMesh::removeOrphanGroups.
659 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
661 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
662 std::vector<std::string> ret;
663 if(!((DataArrayInt*)allFamIdsInUse))
665 ret=getFamiliesNames();
666 _families.clear(); _groups.clear();
669 std::map<std::string,int> famMap;
670 std::map<std::string, std::vector<std::string> > grps(_groups);
671 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
673 if(allFamIdsInUse->presenceOfValue((*it).second))
674 famMap[(*it).first]=(*it).second;
677 ret.push_back((*it).first);
678 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
679 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
681 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
682 std::vector<std::string>& famv=(*it3).second;
683 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
689 { _families=famMap; _groups=grps; }
694 * 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
695 * this family is orphan or not.
697 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
699 void MEDFileMesh::removeFamiliesReferedByNoGroups()
701 std::map<std::string,int> fams;
702 std::set<std::string> sfams;
703 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
704 sfams.insert((*it).first);
705 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
706 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
708 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
709 if(*it!=DFT_FAM_NAME)
710 _families.erase(*it);
714 * 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
715 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
716 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
718 * \sa MEDFileMesh::removeOrphanFamilies
720 void MEDFileMesh::rearrangeFamilies()
722 checkOrphanFamilyZero();
723 removeFamiliesReferedByNoGroups();
725 std::vector<int> levels(getNonEmptyLevelsExt());
726 std::set<int> idsRefed;
727 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
728 idsRefed.insert((*it).second);
729 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
731 const DataArrayInt *fams(0);
734 fams=getFamilyFieldAtLevel(*it);
736 catch(INTERP_KERNEL::Exception& e) { }
739 std::vector<bool> v(fams->getNumberOfTuples(),false);
740 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
741 fams->switchOnTupleEqualTo(*pt,v);
742 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
743 if(!unfetchedIds->empty())
745 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
746 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
747 setFamilyFieldArr(*it,newFams);
750 removeOrphanFamilies();
754 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
756 void MEDFileMesh::checkOrphanFamilyZero() const
758 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
760 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
762 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
763 throw INTERP_KERNEL::Exception(oss.str().c_str());
769 * Renames a group in \a this mesh.
770 * \param [in] oldName - a current name of the group to rename.
771 * \param [in] newName - a new group name.
772 * \throw If no group named \a oldName exists in \a this mesh.
773 * \throw If a group named \a newName already exists.
775 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
777 std::string oname(oldName);
778 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
779 std::vector<std::string> grps=getGroupsNames();
780 if(it==_groups.end())
782 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
783 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
784 throw INTERP_KERNEL::Exception(oss.str().c_str());
786 std::string nname(newName);
787 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
788 if(it2!=_groups.end())
790 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
791 throw INTERP_KERNEL::Exception(oss.str().c_str());
793 std::vector<std::string> cpy=(*it).second;
795 _groups[newName]=cpy;
799 * Changes an id of a family in \a this mesh.
800 * This method calls changeFamilyIdArr().
801 * \param [in] oldId - a current id of the family.
802 * \param [in] newId - a new family id.
804 void MEDFileMesh::changeFamilyId(int oldId, int newId)
806 changeFamilyIdArr(oldId,newId);
807 std::map<std::string,int> fam2;
808 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
810 if((*it).second==oldId)
811 fam2[(*it).first]=newId;
813 fam2[(*it).first]=(*it).second;
819 * Renames a family in \a this mesh.
820 * \param [in] oldName - a current name of the family to rename.
821 * \param [in] newName - a new family name.
822 * \throw If no family named \a oldName exists in \a this mesh.
823 * \throw If a family named \a newName already exists.
825 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
827 std::string oname(oldName);
828 std::map<std::string, int >::iterator it=_families.find(oname);
829 std::vector<std::string> fams=getFamiliesNames();
830 if(it==_families.end())
832 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
833 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
834 throw INTERP_KERNEL::Exception(oss.str().c_str());
836 std::string nname(newName);
837 std::map<std::string, int >::iterator it2=_families.find(nname);
838 if(it2!=_families.end())
840 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
841 throw INTERP_KERNEL::Exception(oss.str().c_str());
843 int cpy=(*it).second;
845 _families[newName]=cpy;
846 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
848 std::vector<std::string>& v=(*it3).second;
849 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
856 * Checks if \a this and another mesh contains the same families.
857 * \param [in] other - the mesh to compare with \a this one.
858 * \param [in,out] what - an unused parameter.
859 * \return bool - \c true if number of families and their ids are the same in the two
860 * meshes. Families with the id == \c 0 are not considered.
862 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
864 if(_families==other->_families)
866 std::map<std::string,int> fam0;
867 std::map<std::string,int> fam1;
868 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
870 fam0[(*it).first]=(*it).second;
871 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
873 fam1[(*it).first]=(*it).second;
878 * Checks if \a this and another mesh contains the same groups.
879 * \param [in] other - the mesh to compare with \a this one.
880 * \param [in,out] what - a string describing a difference of groups of the two meshes
881 * in case if this method returns \c false.
882 * \return bool - \c true if number of groups and families constituting them are the
883 * same in the two meshes.
885 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
887 if(_groups==other->_groups)
890 std::size_t sz=_groups.size();
891 if(sz!=other->_groups.size())
893 what="Groups differ because not same number !\n";
898 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
899 for(std::size_t i=0;i<sz && ret;i++,it1++)
901 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
902 if(it2!=other->_groups.end())
904 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
905 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
911 what="A group in first mesh exists not in other !\n";
917 std::ostringstream oss; oss << "Groups description differs :\n";
918 oss << "First group description :\n";
919 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
921 oss << " Group \"" << (*it).first << "\" on following families :\n";
922 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
923 oss << " \"" << *it2 << "\n";
925 oss << "Second group description :\n";
926 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
928 oss << " Group \"" << (*it).first << "\" on following families :\n";
929 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
930 oss << " \"" << *it2 << "\n";
938 * Checks if a group with a given name exists in \a this mesh.
939 * \param [in] groupName - the group name.
940 * \return bool - \c true the group \a groupName exists in \a this mesh.
942 bool MEDFileMesh::existsGroup(const std::string& groupName) const
944 std::string grpName(groupName);
945 return _groups.find(grpName)!=_groups.end();
949 * Checks if a family with a given id exists in \a this mesh.
950 * \param [in] famId - the family id.
951 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
953 bool MEDFileMesh::existsFamily(int famId) const
955 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
956 if((*it2).second==famId)
962 * Checks if a family with a given name exists in \a this mesh.
963 * \param [in] familyName - the family name.
964 * \return bool - \c true the family \a familyName exists in \a this mesh.
966 bool MEDFileMesh::existsFamily(const std::string& familyName) const
968 std::string fname(familyName);
969 return _families.find(fname)!=_families.end();
973 * Sets an id of a family.
974 * \param [in] familyName - the family name.
975 * \param [in] id - a new id of the family.
977 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
979 std::string fname(familyName);
983 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
985 std::string fname(familyName);
986 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
989 if((*it).first!=familyName)
991 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
992 throw INTERP_KERNEL::Exception(oss.str().c_str());
999 * Adds a family to \a this mesh.
1000 * \param [in] familyName - a name of the family.
1001 * \param [in] famId - an id of the family.
1002 * \throw If a family with the same name or id already exists in \a this mesh.
1004 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1006 std::string fname(familyName);
1007 std::map<std::string,int>::const_iterator it=_families.find(fname);
1008 if(it==_families.end())
1010 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1011 if((*it2).second==famId)
1013 std::ostringstream oss;
1014 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1015 throw INTERP_KERNEL::Exception(oss.str().c_str());
1017 _families[fname]=famId;
1021 if((*it).second!=famId)
1023 std::ostringstream oss;
1024 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1025 throw INTERP_KERNEL::Exception(oss.str().c_str());
1031 * Creates a group including all mesh entities of given dimension.
1032 * \warning This method does \b not guarantee that the created group includes mesh
1033 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1034 * present in family fields of different dimensions. To assure this, call
1035 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1036 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1038 * \param [in] groupName - a name of the new group.
1039 * \throw If a group named \a groupName already exists.
1040 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1041 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1043 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1045 std::string grpName(groupName);
1046 std::vector<int> levs=getNonEmptyLevelsExt();
1047 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1049 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1050 oss << "Available relative ext levels are : ";
1051 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1052 throw INTERP_KERNEL::Exception(oss.str().c_str());
1054 if(existsGroup(groupName))
1056 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1057 oss << "Already existing groups are : ";
1058 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1059 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1060 throw INTERP_KERNEL::Exception(oss.str().c_str());
1062 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1064 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1065 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1066 std::vector<std::string> familiesOnWholeGroup;
1067 for(const int *it=famIds->begin();it!=famIds->end();it++)
1070 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1072 _groups[grpName]=familiesOnWholeGroup;
1076 * Ensures that given family ids do not present in family fields of dimensions different
1077 * than given ones. If a family id is present in the family fields of dimensions different
1078 * than the given ones, a new family is created and the whole data is updated accordingly.
1079 * \param [in] famIds - a sequence of family ids to check.
1080 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1081 * famIds should exclusively belong.
1082 * \return bool - \c true if no modification is done in \a this mesh by this method.
1084 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1086 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1087 std::vector<int> levs=getNonEmptyLevelsExt();
1088 std::set<int> levs2(levs.begin(),levs.end());
1089 std::vector<int> levsToTest;
1090 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1091 std::set<int> famIds2(famIds.begin(),famIds.end());
1094 if(!_families.empty())
1095 maxFamId=getMaxFamilyId()+1;
1096 std::vector<std::string> allFams=getFamiliesNames();
1097 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1099 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1102 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1103 std::vector<int> tmp;
1104 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1105 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1108 std::string famName=getFamilyNameGivenId(*it2);
1109 std::ostringstream oss; oss << "Family_" << maxFamId;
1110 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1111 addFamilyOnAllGroupsHaving(famName,zeName);
1112 _families[zeName]=maxFamId;
1113 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1122 * Adds a family to a given group in \a this mesh. If the group with a given name does
1123 * not exist, it is created.
1124 * \param [in] grpName - the name of the group to add the family in.
1125 * \param [in] famName - the name of the family to add to the group named \a grpName.
1126 * \throw If \a grpName or \a famName is an empty string.
1127 * \throw If no family named \a famName is present in \a this mesh.
1129 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1131 std::string grpn(grpName);
1132 std::string famn(famName);
1133 if(grpn.empty() || famn.empty())
1134 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1135 std::vector<std::string> fams=getFamiliesNames();
1136 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1138 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1139 oss << "Create this family or choose an existing one ! Existing fams are : ";
1140 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1141 throw INTERP_KERNEL::Exception(oss.str().c_str());
1143 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1144 if(it==_groups.end())
1146 _groups[grpn].push_back(famn);
1150 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1151 if(it2==(*it).second.end())
1152 (*it).second.push_back(famn);
1157 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1158 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1159 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1161 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1163 std::string famNameCpp(famName);
1164 std::string otherCpp(otherFamName);
1165 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1167 std::vector<std::string>& v=(*it).second;
1168 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1170 v.push_back(otherCpp);
1176 * \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).
1177 * \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)
1179 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1182 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1183 std::string grpName(ids->getName());
1185 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1186 ids->checkStrictlyMonotonic(true);
1187 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
1188 std::vector<std::string> grpsNames=getGroupsNames();
1189 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1191 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1192 throw INTERP_KERNEL::Exception(oss.str().c_str());
1194 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1195 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1196 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1197 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1198 std::vector<int> familyIds;
1199 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
1200 int maxVal=getTheMaxAbsFamilyId()+1;
1201 std::map<std::string,int> families(_families);
1202 std::map<std::string, std::vector<std::string> > groups(_groups);
1203 std::vector<std::string> fams;
1204 bool created(false);
1205 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1207 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
1208 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1209 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
1210 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1213 bool isFamPresent=false;
1214 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1215 isFamPresent=(*itl)->presenceOfValue(*famId);
1217 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1220 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1221 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1222 fams.push_back(locFamName);
1223 if(existsFamily(*famId))
1225 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1226 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1229 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1233 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1234 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1235 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1236 if(existsFamily(*famId))
1238 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1239 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1244 for(std::size_t i=0;i<familyIds.size();i++)
1246 DataArrayInt *da=idsPerfamiliyIds[i];
1247 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1251 _groups[grpName]=fams;
1254 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1256 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1259 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1261 std::string fam(familyNameToChange);
1262 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1264 std::vector<std::string>& fams((*it).second);
1265 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1269 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1275 * Returns a name of the family having a given id or, if no such a family exists, creates
1276 * a new uniquely named family and returns its name.
1277 * \param [in] id - the id of the family whose name is required.
1278 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1279 * \return std::string - the name of the existing or the created family.
1280 * \throw If it is not possible to create a unique family name.
1282 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1284 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1288 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1289 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1290 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1291 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1293 * This method will throws an exception if it is not possible to create a unique family name.
1295 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1297 std::vector<std::string> famAlreadyExisting(families.size());
1299 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1301 if((*it).second!=id)
1303 famAlreadyExisting[ii]=(*it).first;
1312 std::ostringstream oss; oss << "Family_" << id;
1313 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1319 * Sets names and ids of all families in \a this mesh.
1320 * \param [in] info - a map of a family name to a family id.
1322 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1328 * Sets names of all groups and families constituting them in \a this mesh.
1329 * \param [in] info - a map of a group name to a vector of names of families
1330 * constituting the group.
1332 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1338 * Returns an id of the family having a given name.
1339 * \param [in] name - the name of the family of interest.
1340 * \return int - the id of the family of interest.
1341 * \throw If no family with such a \a name exists.
1343 int MEDFileMesh::getFamilyId(const std::string& name) const
1345 std::string oname(name);
1346 std::map<std::string, int>::const_iterator it=_families.find(oname);
1347 std::vector<std::string> fams=getFamiliesNames();
1348 if(it==_families.end())
1350 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1351 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1352 throw INTERP_KERNEL::Exception(oss.str().c_str());
1354 return (*it).second;
1358 * Returns ids of the families having given names.
1359 * \param [in] fams - a sequence of the names of families of interest.
1360 * \return std::vector<int> - a sequence of the ids of families of interest.
1361 * \throw If \a fams contains a name of an inexistent family.
1363 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1365 std::vector<int> ret(fams.size());
1367 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1369 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1370 if(it2==_families.end())
1372 std::vector<std::string> fams2=getFamiliesNames();
1373 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1374 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1375 throw INTERP_KERNEL::Exception(oss.str().c_str());
1377 ret[i]=(*it2).second;
1383 * Returns a maximal abs(id) of families in \a this mesh.
1384 * \return int - the maximal norm of family id.
1385 * \throw If there are no families in \a this mesh.
1387 int MEDFileMesh::getMaxAbsFamilyId() const
1389 if(_families.empty())
1390 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1391 int ret=-std::numeric_limits<int>::max();
1392 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1394 ret=std::max(std::abs((*it).second),ret);
1400 * Returns a maximal id of families in \a this mesh.
1401 * \return int - the maximal family id.
1402 * \throw If there are no families in \a this mesh.
1404 int MEDFileMesh::getMaxFamilyId() const
1406 if(_families.empty())
1407 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1408 int ret=-std::numeric_limits<int>::max();
1409 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1411 ret=std::max((*it).second,ret);
1417 * Returns a minimal id of families in \a this mesh.
1418 * \return int - the minimal family id.
1419 * \throw If there are no families in \a this mesh.
1421 int MEDFileMesh::getMinFamilyId() const
1423 if(_families.empty())
1424 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1425 int ret=std::numeric_limits<int>::max();
1426 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1428 ret=std::min((*it).second,ret);
1434 * Returns a maximal id of families in \a this mesh. Not only named families are
1435 * considered but all family fields as well.
1436 * \return int - the maximal family id.
1438 int MEDFileMesh::getTheMaxAbsFamilyId() const
1440 int m1=-std::numeric_limits<int>::max();
1441 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1442 m1=std::max(std::abs((*it).second),m1);
1443 int m2=getMaxAbsFamilyIdInArrays();
1444 return std::max(m1,m2);
1448 * Returns a maximal id of families in \a this mesh. Not only named families are
1449 * considered but all family fields as well.
1450 * \return int - the maximal family id.
1452 int MEDFileMesh::getTheMaxFamilyId() const
1454 int m1=-std::numeric_limits<int>::max();
1455 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1456 m1=std::max((*it).second,m1);
1457 int m2=getMaxFamilyIdInArrays();
1458 return std::max(m1,m2);
1462 * Returns a minimal id of families in \a this mesh. Not only named families are
1463 * considered but all family fields as well.
1464 * \return int - the minimal family id.
1466 int MEDFileMesh::getTheMinFamilyId() const
1468 int m1=std::numeric_limits<int>::max();
1469 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1470 m1=std::min((*it).second,m1);
1471 int m2=getMinFamilyIdInArrays();
1472 return std::min(m1,m2);
1476 * This method only considers the maps. The contain of family array is ignored here.
1478 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1480 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1482 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1484 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1485 v.insert((*it).second);
1486 ret->alloc((int)v.size(),1);
1487 std::copy(v.begin(),v.end(),ret->getPointer());
1492 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1494 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1496 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1498 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1499 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1500 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1502 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1503 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1504 if((DataArrayInt *) ret)
1505 ret=dv->buildUnion(ret);
1513 * true is returned if no modification has been needed. false if family
1514 * renumbering has been needed.
1516 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1518 std::vector<int> levs=getNonEmptyLevelsExt();
1519 std::set<int> allFamIds;
1520 int maxId=getMaxFamilyId()+1;
1521 std::map<int,std::vector<int> > famIdsToRenum;
1522 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1524 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1527 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1529 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1531 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1533 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1536 if(famIdsToRenum.empty())
1538 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1539 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1541 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1542 int *famIdsToChange=fam->getPointer();
1543 std::map<int,int> ren;
1544 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1546 if(allIds->presenceOfValue(*it3))
1548 std::string famName=getFamilyNameGivenId(*it3);
1549 std::vector<std::string> grps=getGroupsOnFamily(famName);
1552 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1553 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1554 addFamilyOnGrp((*it4),newFam);
1557 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1558 for(const int *id=ids->begin();id!=ids->end();id++)
1559 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1565 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1566 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1567 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1568 * This method will throw an exception if a same family id is detected in different level.
1569 * \warning This policy is the opposite of those in MED file documentation ...
1571 void MEDFileMesh::normalizeFamIdsTrio()
1573 ensureDifferentFamIdsPerLevel();
1574 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1575 std::vector<int> levs=getNonEmptyLevelsExt();
1576 std::set<int> levsS(levs.begin(),levs.end());
1577 std::set<std::string> famsFetched;
1578 std::map<std::string,int> families;
1579 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1582 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1586 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1587 std::map<int,int> ren;
1588 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1590 int nbOfTuples=fam->getNumberOfTuples();
1591 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1592 for(int *w=start;w!=start+nbOfTuples;w++)
1594 for(const int *it=tmp->begin();it!=tmp->end();it++)
1596 if(allIds->presenceOfValue(*it))
1598 std::string famName=getFamilyNameGivenId(*it);
1599 families[famName]=ren[*it];
1600 famsFetched.insert(famName);
1605 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1608 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1612 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1613 std::map<int,int> ren;
1614 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1616 int nbOfTuples=fam->getNumberOfTuples();
1617 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1618 for(int *w=start;w!=start+nbOfTuples;w++)
1620 for(const int *it=tmp->begin();it!=tmp->end();it++)
1622 if(allIds->presenceOfValue(*it))
1624 std::string famName=getFamilyNameGivenId(*it);
1625 families[famName]=ren[*it];
1626 famsFetched.insert(famName);
1631 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1633 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1636 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1637 fam->fillWithZero();
1638 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1639 if(allIds->presenceOfValue(*it3))
1641 std::string famName=getFamilyNameGivenId(*it3);
1642 families[famName]=0;
1643 famsFetched.insert(famName);
1648 std::vector<std::string> allFams=getFamiliesNames();
1649 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1650 std::set<std::string> unFetchedIds;
1651 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1652 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1653 families[*it4]=_families[*it4];
1658 * This method normalizes fam id with the following policy.
1659 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1660 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1661 * This method will throw an exception if a same family id is detected in different level.
1663 void MEDFileMesh::normalizeFamIdsMEDFile()
1665 ensureDifferentFamIdsPerLevel();
1666 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1667 std::vector<int> levs=getNonEmptyLevelsExt();
1668 std::set<int> levsS(levs.begin(),levs.end());
1669 std::set<std::string> famsFetched;
1670 std::map<std::string,int> families;
1672 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1675 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1678 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1679 std::map<int,int> ren;
1680 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1682 int nbOfTuples=fam->getNumberOfTuples();
1683 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1684 for(int *w=start;w!=start+nbOfTuples;w++)
1686 for(const int *it=tmp->begin();it!=tmp->end();it++)
1688 if(allIds->presenceOfValue(*it))
1690 std::string famName=getFamilyNameGivenId(*it);
1691 families[famName]=ren[*it];
1692 famsFetched.insert(famName);
1698 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1700 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1703 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1704 std::map<int,int> ren;
1705 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1707 int nbOfTuples=fam->getNumberOfTuples();
1708 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1709 for(int *w=start;w!=start+nbOfTuples;w++)
1711 for(const int *it=tmp->begin();it!=tmp->end();it++)
1713 if(allIds->presenceOfValue(*it))
1715 std::string famName=getFamilyNameGivenId(*it);
1716 families[famName]=ren[*it];
1717 famsFetched.insert(famName);
1723 std::vector<std::string> allFams=getFamiliesNames();
1724 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1725 std::set<std::string> unFetchedIds;
1726 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1727 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1728 families[*it4]=_families[*it4];
1733 * Returns a name of the family by its id. If there are several families having the given
1734 * id, the name first in lexical order is returned.
1735 * \param [in] id - the id of the family whose name is required.
1736 * \return std::string - the name of the found family.
1737 * \throw If no family with the given \a id exists.
1739 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1741 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1742 if((*it).second==id)
1744 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1745 throw INTERP_KERNEL::Exception(oss.str().c_str());
1749 * Returns a string describing \a this mesh. This description includes the mesh name and
1750 * the mesh description string.
1751 * \return std::string - the mesh information string.
1753 std::string MEDFileMesh::simpleRepr() const
1755 std::ostringstream oss;
1756 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1757 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1758 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1763 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1764 * an empty one is created.
1766 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1768 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1771 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
1772 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1773 arr->fillWithZero();
1774 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1775 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1779 * Returns ids of mesh entities contained in a given group of a given dimension.
1780 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1782 * \param [in] grp - the name of the group of interest.
1783 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1784 * returned instead of ids.
1785 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1786 * numbers, if available and required, of mesh entities of the group. The caller
1787 * is to delete this array using decrRef() as it is no more needed.
1788 * \throw If the name of a nonexistent group is specified.
1789 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1791 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1793 std::vector<std::string> tmp(1);
1795 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1801 * Returns ids of mesh entities contained in given groups of a given dimension.
1802 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1804 * \param [in] grps - the names of the groups of interest.
1805 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1806 * returned instead of ids.
1807 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1808 * numbers, if available and required, of mesh entities of the groups. The caller
1809 * is to delete this array using decrRef() as it is no more needed.
1810 * \throw If the name of a nonexistent group is present in \a grps.
1811 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1813 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1815 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1816 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1820 * Returns ids of mesh entities contained in a given family of a given dimension.
1821 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1823 * \param [in] fam - the name of the family of interest.
1824 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1825 * returned instead of ids.
1826 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1827 * numbers, if available and required, of mesh entities of the family. The caller
1828 * is to delete this array using decrRef() as it is no more needed.
1829 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1831 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1833 std::vector<std::string> tmp(1);
1835 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1841 * Returns ids of nodes contained in a given group.
1842 * \param [in] grp - the name of the group of interest.
1843 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1844 * returned instead of ids.
1845 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1846 * numbers, if available and required, of nodes of the group. The caller
1847 * is to delete this array using decrRef() as it is no more needed.
1848 * \throw If the name of a nonexistent group is specified.
1849 * \throw If the family field is missing for nodes.
1851 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1853 std::vector<std::string> tmp(1);
1855 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1861 * Returns ids of nodes contained in given groups.
1862 * \param [in] grps - the names of the groups of interest.
1863 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1864 * returned instead of ids.
1865 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1866 * numbers, if available and required, of nodes of the groups. The caller
1867 * is to delete this array using decrRef() as it is no more needed.
1868 * \throw If the name of a nonexistent group is present in \a grps.
1869 * \throw If the family field is missing for nodes.
1871 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1873 return getGroupsArr(1,grps,renum);
1877 * Returns ids of nodes contained in a given group.
1878 * \param [in] grp - the name of the group of interest.
1879 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1880 * returned instead of ids.
1881 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1882 * numbers, if available and required, of nodes of the group. The caller
1883 * is to delete this array using decrRef() as it is no more needed.
1884 * \throw If the name of a nonexistent group is specified.
1885 * \throw If the family field is missing for nodes.
1887 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1889 std::vector<std::string> tmp(1);
1891 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1897 * Returns ids of nodes contained in given families.
1898 * \param [in] fams - the names of the families of interest.
1899 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1900 * returned instead of ids.
1901 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1902 * numbers, if available and required, of nodes of the families. The caller
1903 * is to delete this array using decrRef() as it is no more needed.
1904 * \throw If the family field is missing for nodes.
1906 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1908 return getFamiliesArr(1,fams,renum);
1912 * Adds groups of given dimension and creates corresponding families and family fields
1913 * given ids of mesh entities of each group.
1914 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1915 * \param [in] grps - a sequence of arrays of ids each describing a group.
1916 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1918 * \throw If names of some groups in \a grps are equal.
1919 * \throw If \a grps includes a group with an empty name.
1920 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1921 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1923 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1927 std::set<std::string> grpsName;
1928 std::vector<std::string> grpsName2(grps.size());
1931 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1933 grpsName.insert((*it)->getName());
1934 grpsName2[i]=(*it)->getName();
1936 if(grpsName.size()!=grps.size())
1937 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1938 if(grpsName.find(std::string(""))!=grpsName.end())
1939 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1940 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1941 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1942 std::vector< std::vector<int> > fidsOfGroups;
1945 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1949 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1950 for(unsigned int ii=0;ii<grps.size();ii++)
1952 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1953 grps2[ii]->setName(grps[ii]->getName());
1955 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1956 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1959 if(!_families.empty())
1960 offset=getMaxAbsFamilyId()+1;
1961 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1962 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1963 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1964 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1968 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1969 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1970 * For the moment, the two last input parameters are not taken into account.
1972 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1974 std::map<int,std::string> famInv;
1975 for(const int *it=famIds->begin();it!=famIds->end();it++)
1977 std::ostringstream oss;
1978 oss << "Family_" << (*it);
1979 _families[oss.str()]=(*it);
1980 famInv[*it]=oss.str();
1983 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1985 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1987 _groups[grpNames[i]].push_back(famInv[*it2]);
1992 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1994 std::vector<int> levs(getNonEmptyLevels());
1995 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1996 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1998 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1999 ret.insert(ret.end(),elts.begin(),elts.end());
2004 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2006 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
2007 return mLev->getDistributionOfTypes();
2010 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2012 loadLL(fid,mName,dt,it,mrs);
2013 loadJointsFromFile(fid);
2014 loadEquivalences(fid);
2017 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2019 famArr->applyLin(offset>0?1:-1,offset,0);
2020 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2023 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2024 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2029 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2030 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2031 * If this method fails to find such a name it will throw an exception.
2033 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2036 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2039 std::size_t len=nameTry.length();
2040 for(std::size_t ii=1;ii<len;ii++)
2042 std::string tmp=nameTry.substr(ii,len-ii);
2043 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2049 for(std::size_t i=1;i<30;i++)
2051 std::string tmp1(nameTry.at(0),i);
2053 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2059 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2061 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2063 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2066 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2068 std::size_t nbOfChunks=code.size()/3;
2069 if(code.size()%3!=0)
2070 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2072 for(std::size_t i=0;i<nbOfChunks;i++)
2081 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2082 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2083 * If _name is not empty and that 'm' has the same name nothing is done.
2084 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2086 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2089 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2094 std::string name(m->getName());
2099 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2100 oss << name << "' ! Names must match !";
2101 throw INTERP_KERNEL::Exception(oss.str().c_str());
2105 if(_desc_name.empty())
2106 _desc_name=m->getDescription();
2109 std::string name(m->getDescription());
2112 if(_desc_name!=name)
2114 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2115 oss << name << "' ! Names must match !";
2116 throw INTERP_KERNEL::Exception(oss.str().c_str());
2122 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2124 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2125 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2127 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2128 oss << " - Groups lying on this family : ";
2129 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2130 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2131 oss << std::endl << std::endl;
2136 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2137 * file. The mesh to load is specified by its name and numbers of a time step and an
2139 * \param [in] fileName - the name of MED file to read.
2140 * \param [in] mName - the name of the mesh to read.
2141 * \param [in] dt - the number of a time step.
2142 * \param [in] it - the number of an iteration.
2143 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2144 * mesh using decrRef() as it is no more needed.
2145 * \throw If the file is not readable.
2146 * \throw If there is no mesh with given attributes in the file.
2147 * \throw If the mesh in the file is not an unstructured one.
2149 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2151 MEDFileUtilities::CheckFileForRead(fileName);
2152 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2153 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2157 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2158 * file. The first mesh in the file is loaded.
2159 * \param [in] fileName - the name of MED file to read.
2160 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2161 * mesh using decrRef() as it is no more needed.
2162 * \throw If the file is not readable.
2163 * \throw If there is no meshes in the file.
2164 * \throw If the mesh in the file is not an unstructured one.
2166 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2168 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2171 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2172 throw INTERP_KERNEL::Exception(oss.str().c_str());
2174 MEDFileUtilities::CheckFileForRead(fileName);
2175 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2177 ParaMEDMEM::MEDCouplingMeshType meshType;
2179 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
2180 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2184 * Returns an empty instance of MEDFileUMesh.
2185 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2186 * mesh using decrRef() as it is no more needed.
2188 MEDFileUMesh *MEDFileUMesh::New()
2190 return new MEDFileUMesh;
2194 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2195 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2196 * \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.
2197 * 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
2198 * at most the memory consumtion.
2200 * \param [in] fileName - the name of the file.
2201 * \param [in] mName - the name of the mesh to be read.
2202 * \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.
2203 * \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.
2204 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2205 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2206 * \param [in] mrs - the request for what to be loaded.
2207 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2209 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)
2211 MEDFileUtilities::CheckFileForRead(fileName);
2212 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2213 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2217 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2218 * This method is \b NOT wrapped into python.
2220 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)
2222 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2223 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2227 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2229 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2230 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2234 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2236 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2237 ret.push_back((const DataArrayDouble*)_coords);
2238 ret.push_back((const DataArrayInt *)_fam_coords);
2239 ret.push_back((const DataArrayInt *)_num_coords);
2240 ret.push_back((const DataArrayInt *)_rev_num_coords);
2241 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2242 ret.push_back((const PartDefinition *)_part_coords);
2243 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2244 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2248 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2250 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2254 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2256 return new MEDFileUMesh;
2259 MEDFileMesh *MEDFileUMesh::deepCpy() const
2261 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2262 ret->deepCpyEquivalences(*this);
2263 if((const DataArrayDouble*)_coords)
2264 ret->_coords=_coords->deepCpy();
2265 if((const DataArrayInt*)_fam_coords)
2266 ret->_fam_coords=_fam_coords->deepCpy();
2267 if((const DataArrayInt*)_num_coords)
2268 ret->_num_coords=_num_coords->deepCpy();
2269 if((const DataArrayInt*)_rev_num_coords)
2270 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2271 if((const DataArrayAsciiChar*)_name_coords)
2272 ret->_name_coords=_name_coords->deepCpy();
2274 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2276 if((const MEDFileUMeshSplitL1 *)(*it))
2277 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2279 if((const PartDefinition*)_part_coords)
2280 ret->_part_coords=_part_coords->deepCpy();
2285 * Checks if \a this and another mesh are equal.
2286 * \param [in] other - the mesh to compare with.
2287 * \param [in] eps - a precision used to compare real values.
2288 * \param [in,out] what - the string returning description of unequal data.
2289 * \return bool - \c true if the meshes are equal, \c false, else.
2291 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2293 if(!MEDFileMesh::isEqual(other,eps,what))
2295 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2298 what="Mesh types differ ! This is unstructured and other is NOT !";
2301 clearNonDiscrAttributes();
2302 otherC->clearNonDiscrAttributes();
2303 const DataArrayDouble *coo1=_coords;
2304 const DataArrayDouble *coo2=otherC->_coords;
2305 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2307 what="Mismatch of coordinates ! One is defined and not other !";
2312 bool ret=coo1->isEqual(*coo2,eps);
2315 what="Coords differ !";
2319 const DataArrayInt *famc1=_fam_coords;
2320 const DataArrayInt *famc2=otherC->_fam_coords;
2321 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2323 what="Mismatch of families arr on nodes ! One is defined and not other !";
2328 bool ret=famc1->isEqual(*famc2);
2331 what="Families arr on node differ !";
2335 const DataArrayInt *numc1=_num_coords;
2336 const DataArrayInt *numc2=otherC->_num_coords;
2337 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2339 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2344 bool ret=numc1->isEqual(*numc2);
2347 what="Numbering arr on node differ !";
2351 const DataArrayAsciiChar *namec1=_name_coords;
2352 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2353 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2355 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2360 bool ret=namec1->isEqual(*namec2);
2363 what="Names arr on node differ !";
2367 if(_ms.size()!=otherC->_ms.size())
2369 what="Number of levels differs !";
2372 std::size_t sz=_ms.size();
2373 for(std::size_t i=0;i<sz;i++)
2375 const MEDFileUMeshSplitL1 *s1=_ms[i];
2376 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2377 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2379 what="Mismatch of presence of sub levels !";
2384 bool ret=s1->isEqual(s2,eps,what);
2389 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2392 if((!pd0 && pd1) || (pd0 && !pd1))
2394 what=std::string("node part def is defined only for one among this or other !");
2397 return pd0->isEqual(pd1,what);
2401 * Clears redundant attributes of incorporated data arrays.
2403 void MEDFileUMesh::clearNonDiscrAttributes() const
2405 MEDFileMesh::clearNonDiscrAttributes();
2406 const DataArrayDouble *coo1=_coords;
2408 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2409 const DataArrayInt *famc1=_fam_coords;
2411 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2412 const DataArrayInt *numc1=_num_coords;
2414 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2415 const DataArrayAsciiChar *namc1=_name_coords;
2417 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2418 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2420 const MEDFileUMeshSplitL1 *tmp=(*it);
2422 tmp->clearNonDiscrAttributes();
2426 void MEDFileUMesh::setName(const std::string& name)
2428 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2429 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2430 (*it)->setName(name);
2431 MEDFileMesh::setName(name);
2434 MEDFileUMesh::MEDFileUMesh()
2438 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2441 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2443 catch(INTERP_KERNEL::Exception& e)
2449 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2450 * See MEDFileUMesh::LoadPartOf for detailed description.
2454 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)
2456 MEDFileUMeshL2 loaderl2;
2457 ParaMEDMEM::MEDCouplingMeshType meshType;
2460 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2461 if(meshType!=UNSTRUCTURED)
2463 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2464 throw INTERP_KERNEL::Exception(oss.str().c_str());
2466 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2467 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2471 * \brief Write joints in a file
2473 void MEDFileMesh::writeJoints(med_idt fid) const
2475 if ( (const MEDFileJoints*) _joints )
2476 _joints->write(fid);
2480 * \brief Load joints in a file or use provided ones
2482 //================================================================================
2484 * \brief Load joints in a file or use provided ones
2485 * \param [in] fid - MED file descriptor
2486 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2487 * Usually this joints are those just read by another iteration
2488 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2490 //================================================================================
2492 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2494 if ( toUseInstedOfReading )
2495 setJoints( toUseInstedOfReading );
2497 _joints = MEDFileJoints::New( fid, _name );
2500 void MEDFileMesh::loadEquivalences(med_idt fid)
2502 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2504 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2507 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2509 const MEDFileEquivalences *equiv(other._equiv);
2511 _equiv=equiv->deepCpy(this);
2514 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2516 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2517 if(!thisEq && !otherEq)
2519 if(thisEq && otherEq)
2520 return thisEq->isEqual(otherEq,what);
2523 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2528 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2530 const MEDFileEquivalences *equiv(_equiv);
2533 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2534 _equiv->getRepr(oss);
2538 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2540 int MEDFileMesh::getNumberOfJoints() const
2542 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2546 * \brief Return joints with all adjacent mesh domains
2548 MEDFileJoints * MEDFileMesh::getJoints() const
2550 return const_cast<MEDFileJoints*>(& (*_joints));
2553 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2555 if ( joints != _joints )
2564 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2566 * \sa loadPartUMeshFromFile
2568 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2570 MEDFileUMeshL2 loaderl2;
2571 ParaMEDMEM::MEDCouplingMeshType meshType;
2574 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2575 if(meshType!=UNSTRUCTURED)
2577 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2578 throw INTERP_KERNEL::Exception(oss.str().c_str());
2580 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2581 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2584 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2586 int lev=loaderl2.getNumberOfLevels();
2588 for(int i=0;i<lev;i++)
2590 if(!loaderl2.emptyLev(i))
2591 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2595 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2597 setName(loaderl2.getName());
2598 setDescription(loaderl2.getDescription());
2599 setUnivName(loaderl2.getUnivName());
2600 setIteration(loaderl2.getIteration());
2601 setOrder(loaderl2.getOrder());
2602 setTimeValue(loaderl2.getTime());
2603 setTimeUnit(loaderl2.getTimeUnit());
2604 _coords=loaderl2.getCoords();
2605 if(!mrs || mrs->isNodeFamilyFieldReading())
2606 _fam_coords=loaderl2.getCoordsFamily();
2607 if(!mrs || mrs->isNodeNumFieldReading())
2608 _num_coords=loaderl2.getCoordsNum();
2609 if(!mrs || mrs->isNodeNameFieldReading())
2610 _name_coords=loaderl2.getCoordsName();
2611 _part_coords=loaderl2.getPartDefOfCoo();
2615 MEDFileUMesh::~MEDFileUMesh()
2619 void MEDFileUMesh::writeLL(med_idt fid) const
2621 const DataArrayDouble *coo=_coords;
2622 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2623 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2624 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2625 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2626 int spaceDim=coo?coo->getNumberOfComponents():0;
2629 mdim=getMeshDimension();
2630 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2631 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2632 for(int i=0;i<spaceDim;i++)
2634 std::string info=coo->getInfoOnComponent(i);
2636 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2637 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
2638 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
2640 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
2642 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2643 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2644 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2645 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2646 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2647 (*it)->write(fid,meshName,mdim);
2648 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2652 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2653 * \return std::vector<int> - a sequence of the relative dimensions.
2655 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2657 std::vector<int> ret;
2659 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2660 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2667 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2668 * \return std::vector<int> - a sequence of the relative dimensions.
2670 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2672 std::vector<int> ret0=getNonEmptyLevels();
2673 if((const DataArrayDouble *) _coords)
2675 std::vector<int> ret(ret0.size()+1);
2677 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2683 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2685 std::vector<int> ret;
2686 const DataArrayInt *famCoo(_fam_coords);
2690 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2692 const MEDFileUMeshSplitL1 *cur(*it);
2694 if(cur->getFamilyField())
2700 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2702 std::vector<int> ret;
2703 const DataArrayInt *numCoo(_num_coords);
2707 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2709 const MEDFileUMeshSplitL1 *cur(*it);
2711 if(cur->getNumberField())
2717 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2719 std::vector<int> ret;
2720 const DataArrayAsciiChar *nameCoo(_name_coords);
2724 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2726 const MEDFileUMeshSplitL1 *cur(*it);
2728 if(cur->getNameField())
2735 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2736 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2737 * \param [in] grp - the name of the group of interest.
2738 * \return std::vector<int> - a sequence of the relative dimensions.
2740 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2742 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2743 return getFamsNonEmptyLevels(fams);
2747 * Returns all relative mesh levels (including nodes) where a given group is defined.
2748 * \param [in] grp - the name of the group of interest.
2749 * \return std::vector<int> - a sequence of the relative dimensions.
2751 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2753 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2754 return getFamsNonEmptyLevelsExt(fams);
2758 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2759 * To include nodes, call getFamNonEmptyLevelsExt() method.
2760 * \param [in] fam - the name of the family of interest.
2761 * \return std::vector<int> - a sequence of the relative dimensions.
2763 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2765 std::vector<std::string> fams(1,std::string(fam));
2766 return getFamsNonEmptyLevels(fams);
2770 * Returns all relative mesh levels (including nodes) where a given family is defined.
2771 * \param [in] fam - the name of the family of interest.
2772 * \return std::vector<int> - a sequence of the relative dimensions.
2774 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2776 std::vector<std::string> fams(1,std::string(fam));
2777 return getFamsNonEmptyLevelsExt(fams);
2781 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2782 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2783 * \param [in] grps - a sequence of names of the groups of interest.
2784 * \return std::vector<int> - a sequence of the relative dimensions.
2786 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2788 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2789 return getFamsNonEmptyLevels(fams);
2793 * Returns all relative mesh levels (including nodes) where given groups are defined.
2794 * \param [in] grps - a sequence of names of the groups of interest.
2795 * \return std::vector<int> - a sequence of the relative dimensions.
2797 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2799 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2800 return getFamsNonEmptyLevelsExt(fams);
2804 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2805 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2806 * \param [in] fams - the name of the family of interest.
2807 * \return std::vector<int> - a sequence of the relative dimensions.
2809 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2811 std::vector<int> ret;
2812 std::vector<int> levs=getNonEmptyLevels();
2813 std::vector<int> famIds=getFamiliesIds(fams);
2814 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2815 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2821 * Returns all relative mesh levels (including nodes) where given families are defined.
2822 * \param [in] fams - the names of the families of interest.
2823 * \return std::vector<int> - a sequence of the relative dimensions.
2825 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2827 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2828 const DataArrayInt *famCoords=_fam_coords;
2831 std::vector<int> famIds=getFamiliesIds(fams);
2832 if(famCoords->presenceOfValue(famIds))
2834 std::vector<int> ret(ret0.size()+1);
2836 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2844 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2845 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2846 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2849 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2851 std::vector<std::string> ret;
2852 std::vector<std::string> allGrps=getGroupsNames();
2853 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2855 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2856 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2862 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2864 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2865 if((const DataArrayInt *)_fam_coords)
2867 int val=_fam_coords->getMaxValue(tmp);
2868 ret=std::max(ret,std::abs(val));
2870 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2872 if((const MEDFileUMeshSplitL1 *)(*it))
2874 const DataArrayInt *da=(*it)->getFamilyField();
2877 int val=da->getMaxValue(tmp);
2878 ret=std::max(ret,std::abs(val));
2885 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2887 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2888 if((const DataArrayInt *)_fam_coords)
2890 int val=_fam_coords->getMaxValue(tmp);
2891 ret=std::max(ret,val);
2893 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2895 if((const MEDFileUMeshSplitL1 *)(*it))
2897 const DataArrayInt *da=(*it)->getFamilyField();
2900 int val=da->getMaxValue(tmp);
2901 ret=std::max(ret,val);
2908 int MEDFileUMesh::getMinFamilyIdInArrays() const
2910 int ret=std::numeric_limits<int>::max(),tmp=-1;
2911 if((const DataArrayInt *)_fam_coords)
2913 int val=_fam_coords->getMinValue(tmp);
2914 ret=std::min(ret,val);
2916 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2918 if((const MEDFileUMeshSplitL1 *)(*it))
2920 const DataArrayInt *da=(*it)->getFamilyField();
2923 int val=da->getMinValue(tmp);
2924 ret=std::min(ret,val);
2932 * Returns the dimension on cells in \a this mesh.
2933 * \return int - the mesh dimension.
2934 * \throw If there are no cells in this mesh.
2936 int MEDFileUMesh::getMeshDimension() const
2939 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2940 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2941 return (*it)->getMeshDimension()+lev;
2942 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2946 * Returns the space dimension of \a this mesh that is equal to number of components in
2947 * the node coordinates array.
2948 * \return int - the space dimension of \a this mesh.
2949 * \throw If the node coordinates array is not available.
2951 int MEDFileUMesh::getSpaceDimension() const
2953 const DataArrayDouble *coo=_coords;
2955 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2956 return coo->getNumberOfComponents();
2960 * Returns a string describing \a this mesh.
2961 * \return std::string - the mesh information string.
2963 std::string MEDFileUMesh::simpleRepr() const
2965 std::ostringstream oss;
2966 oss << MEDFileMesh::simpleRepr();
2967 const DataArrayDouble *coo=_coords;
2968 oss << "- The dimension of the space is ";
2969 static const char MSG1[]= "*** NO COORDS SET ***";
2970 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2972 oss << _coords->getNumberOfComponents() << std::endl;
2974 oss << MSG1 << std::endl;
2975 oss << "- Type of the mesh : UNSTRUCTURED\n";
2976 oss << "- Number of nodes : ";
2978 oss << _coords->getNumberOfTuples() << std::endl;
2980 oss << MSG1 << std::endl;
2981 std::size_t nbOfLev=_ms.size();
2982 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2983 for(std::size_t i=0;i<nbOfLev;i++)
2985 const MEDFileUMeshSplitL1 *lev=_ms[i];
2986 oss << " - Level #" << -((int) i) << " has dimension : ";
2989 oss << lev->getMeshDimension() << std::endl;
2990 lev->simpleRepr(oss);
2993 oss << MSG2 << std::endl;
2995 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2998 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2999 oss << "- Names of coordinates :" << std::endl;
3000 std::vector<std::string> vars=coo->getVarsOnComponent();
3001 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3002 oss << std::endl << "- Units of coordinates : " << std::endl;
3003 std::vector<std::string> units=coo->getUnitsOnComponent();
3004 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3006 oss << std::endl << std::endl;
3008 getEquivalencesRepr(oss);
3013 * Returns a full textual description of \a this mesh.
3014 * \return std::string - the string holding the mesh description.
3016 std::string MEDFileUMesh::advancedRepr() const
3018 return simpleRepr();
3022 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3023 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3024 * \return int - the number of entities.
3025 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3027 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3029 if(meshDimRelToMaxExt==1)
3031 if(!((const DataArrayDouble *)_coords))
3032 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3033 return _coords->getNumberOfTuples();
3035 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3039 * Returns the family field for mesh entities of a given dimension.
3040 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3041 * \return const DataArrayInt * - the family field. It is an array of ids of families
3042 * each mesh entity belongs to. It can be \c NULL.
3044 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3046 if(meshDimRelToMaxExt==1)
3048 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3049 return l1->getFamilyField();
3052 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3054 if(meshDimRelToMaxExt==1)
3056 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3057 return l1->getFamilyField();
3061 * Returns the optional numbers of mesh entities of a given dimension.
3062 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3063 * \return const DataArrayInt * - the array of the entity numbers.
3064 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3066 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3068 if(meshDimRelToMaxExt==1)
3070 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3071 return l1->getNumberField();
3074 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3076 if(meshDimRelToMaxExt==1)
3077 return _name_coords;
3078 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3079 return l1->getNameField();
3083 * 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).
3085 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3086 * \param [in] gt - The input geometric type for which the part definition is requested.
3087 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3089 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3091 if(meshDimRelToMaxExt==1)
3092 return _part_coords;
3093 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3094 return l1->getPartDef(gt);
3097 int MEDFileUMesh::getNumberOfNodes() const
3099 const DataArrayDouble *coo(_coords);
3101 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3102 return coo->getNumberOfTuples();
3105 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3107 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3108 return l1->getNumberOfCells();
3111 bool MEDFileUMesh::hasImplicitPart() const
3116 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3118 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3121 void MEDFileUMesh::releaseImplicitPartIfAny() const
3125 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3127 std::size_t sz(st.getNumberOfItems());
3128 for(std::size_t i=0;i<sz;i++)
3130 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3131 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3132 if(st[i].getPflName().empty())
3133 m->computeNodeIdsAlg(nodesFetched);
3136 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3137 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3138 m2->computeNodeIdsAlg(nodesFetched);
3144 * Returns the optional numbers of mesh entities of a given dimension transformed using
3145 * DataArrayInt::invertArrayN2O2O2N().
3146 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3147 * \return const DataArrayInt * - the array of the entity numbers transformed using
3148 * DataArrayInt::invertArrayN2O2O2N().
3149 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3151 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3153 if(meshDimRelToMaxExt==1)
3155 if(!((const DataArrayInt *)_num_coords))
3156 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3157 return _rev_num_coords;
3159 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3160 return l1->getRevNumberField();
3164 * Returns a pointer to the node coordinates array of \a this mesh \b without
3165 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3167 DataArrayDouble *MEDFileUMesh::getCoords() const
3169 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
3170 if((DataArrayDouble *)tmp)
3178 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3179 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3181 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3182 * \param [in] grp - the name of the group whose mesh entities are included in the
3184 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3185 * according to the optional numbers of entities, if available.
3186 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3187 * delete this mesh using decrRef() as it is no more needed.
3188 * \throw If the name of a nonexistent group is specified.
3189 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3191 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3193 synchronizeTinyInfoOnLeaves();
3194 std::vector<std::string> tmp(1);
3196 return getGroups(meshDimRelToMaxExt,tmp,renum);
3200 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3201 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3203 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3204 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3206 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3207 * according to the optional numbers of entities, if available.
3208 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3209 * delete this mesh using decrRef() as it is no more needed.
3210 * \throw If a name of a nonexistent group is present in \a grps.
3211 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3213 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3215 synchronizeTinyInfoOnLeaves();
3216 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3217 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3218 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3219 zeRet->setName(grps[0]);
3220 return zeRet.retn();
3224 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3225 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3227 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3228 * \param [in] fam - the name of the family whose mesh entities are included in the
3230 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3231 * according to the optional numbers of entities, if available.
3232 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3233 * delete this mesh using decrRef() as it is no more needed.
3234 * \throw If a name of a nonexistent family is present in \a grps.
3235 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3237 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3239 synchronizeTinyInfoOnLeaves();
3240 std::vector<std::string> tmp(1);
3242 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3246 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3247 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3249 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3250 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3252 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3253 * according to the optional numbers of entities, if available.
3254 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3255 * delete this mesh using decrRef() as it is no more needed.
3256 * \throw If a name of a nonexistent family is present in \a fams.
3257 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3259 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3261 synchronizeTinyInfoOnLeaves();
3262 if(meshDimRelToMaxExt==1)
3264 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3265 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3266 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3270 std::vector<int> famIds=getFamiliesIds(fams);
3271 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3272 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3274 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3276 zeRet=l1->getFamilyPart(0,0,renum);
3277 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3278 zeRet->setName(fams[0]);
3279 return zeRet.retn();
3283 * Returns ids of mesh entities contained in given families of a given dimension.
3284 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3286 * \param [in] fams - the names of the families of interest.
3287 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3288 * returned instead of ids.
3289 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3290 * numbers, if available and required, of mesh entities of the families. The caller
3291 * is to delete this array using decrRef() as it is no more needed.
3292 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3294 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3296 std::vector<int> famIds=getFamiliesIds(fams);
3297 if(meshDimRelToMaxExt==1)
3299 if((const DataArrayInt *)_fam_coords)
3301 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3303 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3305 da=_fam_coords->getIdsEqualList(0,0);
3307 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3312 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3314 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3316 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3318 return l1->getFamilyPartArr(0,0,renum);
3322 * Returns a MEDCouplingUMesh of a given relative dimension.
3323 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3324 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3325 * To build a valid MEDCouplingUMesh from the returned one in this case,
3326 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3327 * \param [in] meshDimRelToMax - the relative dimension of interest.
3328 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3329 * optional numbers of mesh entities.
3330 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3331 * delete using decrRef() as it is no more needed.
3332 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3333 * \sa getGenMeshAtLevel()
3335 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3337 synchronizeTinyInfoOnLeaves();
3338 if(meshDimRelToMaxExt==1)
3342 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3343 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3344 umesh->setCoords(cc);
3345 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3346 umesh->setName(getName());
3350 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3351 return l1->getWholeMesh(renum);
3355 * Returns a MEDCouplingUMesh of a given relative dimension.
3356 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3357 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3358 * To build a valid MEDCouplingUMesh from the returned one in this case,
3359 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3360 * \param [in] meshDimRelToMax - the relative dimension of interest.
3361 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3362 * optional numbers of mesh entities.
3363 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3364 * delete using decrRef() as it is no more needed.
3365 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3366 * \sa getMeshAtLevel()
3368 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3370 return getMeshAtLevel(meshDimRelToMax,renum);
3373 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3375 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3376 return l1->getDistributionOfTypes();
3380 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3381 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3382 * optional numbers of mesh entities.
3383 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3384 * delete using decrRef() as it is no more needed.
3385 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3387 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3389 return getMeshAtLevel(0,renum);
3393 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3394 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3395 * optional numbers of mesh entities.
3396 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3397 * delete using decrRef() as it is no more needed.
3398 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3400 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3402 return getMeshAtLevel(-1,renum);
3406 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3407 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3408 * optional numbers of mesh entities.
3409 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3410 * delete using decrRef() as it is no more needed.
3411 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3413 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3415 return getMeshAtLevel(-2,renum);
3419 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3420 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3421 * optional numbers of mesh entities.
3422 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3423 * delete using decrRef() as it is no more needed.
3424 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3426 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3428 return getMeshAtLevel(-3,renum);
3432 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3433 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3434 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3435 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3437 void MEDFileUMesh::forceComputationOfParts() const
3439 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3441 const MEDFileUMeshSplitL1 *elt(*it);
3443 elt->forceComputationOfParts();
3448 * This method returns a vector of mesh parts containing each exactly one geometric type.
3449 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3450 * This method is only for memory aware users.
3451 * The returned pointers are **NOT** new object pointer. No need to mange them.
3453 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3455 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3456 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3460 * This method returns the part of \a this having the geometric type \a gt.
3461 * If such part is not existing an exception will be thrown.
3462 * The returned pointer is **NOT** new object pointer. No need to mange it.
3464 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3466 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3467 int lev=(int)cm.getDimension()-getMeshDimension();
3468 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3469 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3473 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3474 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3476 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3478 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3479 return sp->getGeoTypes();
3482 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3484 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3485 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3486 return sp->getNumberOfCellsWithType(ct);
3490 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3491 * \param [in] gt - the geometric type for which the family field is asked.
3492 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3493 * delete using decrRef() as it is no more needed.
3494 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3496 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3498 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3499 int lev=(int)cm.getDimension()-getMeshDimension();
3500 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3501 return sp->extractFamilyFieldOnGeoType(gt);
3505 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3506 * \param [in] gt - the geometric type for which the number field is asked.
3507 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3508 * delete using decrRef() as it is no more needed.
3509 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3511 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3513 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3514 int lev=(int)cm.getDimension()-getMeshDimension();
3515 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3516 return sp->extractNumberFieldOnGeoType(gt);
3520 * This method returns for specified geometric type \a gt the relative level to \a this.
3521 * If the relative level is empty an exception will be thrown.
3523 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3525 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3526 int ret((int)cm.getDimension()-getMeshDimension());
3527 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3531 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3533 if(meshDimRelToMaxExt==1)
3534 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3535 if(meshDimRelToMaxExt>1)
3536 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3537 int tracucedRk=-meshDimRelToMaxExt;
3538 if(tracucedRk>=(int)_ms.size())
3539 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3540 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3541 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3542 return _ms[tracucedRk];
3545 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3547 if(meshDimRelToMaxExt==1)
3548 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3549 if(meshDimRelToMaxExt>1)
3550 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3551 int tracucedRk=-meshDimRelToMaxExt;
3552 if(tracucedRk>=(int)_ms.size())
3553 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3554 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3555 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3556 return _ms[tracucedRk];
3559 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3561 if(-meshDimRelToMax>=(int)_ms.size())
3562 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3564 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3566 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3568 int ref=(*it)->getMeshDimension();
3569 if(ref+i!=meshDim-meshDimRelToMax)
3570 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3576 * Sets the node coordinates array of \a this mesh.
3577 * \param [in] coords - the new node coordinates array.
3578 * \throw If \a coords == \c NULL.
3580 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3583 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3584 coords->checkAllocated();
3585 int nbOfTuples=coords->getNumberOfTuples();
3588 _fam_coords=DataArrayInt::New();
3589 _fam_coords->alloc(nbOfTuples,1);
3590 _fam_coords->fillWithZero();
3591 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3592 if((MEDFileUMeshSplitL1 *)(*it))
3593 (*it)->setCoords(coords);
3597 * Removes all groups of a given dimension in \a this mesh.
3598 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3599 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3601 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3603 if(meshDimRelToMaxExt==1)
3605 if((DataArrayInt *)_fam_coords)
3606 _fam_coords->fillWithZero();
3609 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3610 l1->eraseFamilyField();
3615 * Removes all families with ids not present in the family fields of \a this mesh.
3617 void MEDFileUMesh::optimizeFamilies()
3619 std::vector<int> levs=getNonEmptyLevelsExt();
3620 std::set<int> allFamsIds;
3621 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3623 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3624 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3626 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3629 std::set<std::string> famNamesToKill;
3630 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3632 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3633 famNamesToKill.insert((*it).first);
3635 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3636 _families.erase(*it);
3637 std::vector<std::string> grpNamesToKill;
3638 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3640 std::vector<std::string> tmp;
3641 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3643 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3644 tmp.push_back(*it2);
3649 tmp.push_back((*it).first);
3651 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3656 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3657 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3658 * The boundary is built according to the following method:
3659 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3660 * coordinates array is extended).
3661 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated.
3662 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3663 * other side of the group is no more a neighbor)
3664 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3665 * bordering the newly created boundary use the newly computed nodes.
3667 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3668 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3670 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3671 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3673 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3674 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3676 std::vector<int> levs=getNonEmptyLevels();
3677 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3678 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3679 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3680 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3681 int nbNodes=m0->getNumberOfNodes();
3682 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3683 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3684 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3685 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3686 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3687 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3688 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3689 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3690 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3691 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3692 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3693 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3694 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3695 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3696 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3697 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3698 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3699 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3700 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3701 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3702 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3703 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3704 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3705 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3706 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3707 m0->setCoords(tmp0->getCoords());
3708 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3709 m1->setCoords(m0->getCoords());
3710 _coords=m0->getCoords(); _coords->incrRef();
3711 // duplication of cells in group 'grpNameM1' on level -1
3712 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3713 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3714 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3715 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3716 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3718 newm1->setName(getName());
3719 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3721 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !");
3722 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3723 newFam->alloc(newm1->getNumberOfCells(),1);
3724 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3725 // Positive ID for family of nodes, negative for all the rest.
3727 if (m1->getMeshDimension() == 0)
3728 idd=getMaxFamilyId()+1;
3730 idd=getMinFamilyId()-1;
3731 int globStart=0,start=0,end,globEnd;
3732 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3733 for(int i=0;i<nbOfChunks;i++)
3735 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3736 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3738 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3739 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3740 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3745 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3749 newm1->setCoords(getCoords());
3750 setMeshAtLevel(-1,newm1);
3751 setFamilyFieldArr(-1,newFam);
3752 std::string grpName2(grpNameM1); grpName2+="_dup";
3753 addFamily(grpName2,idd);
3754 addFamilyOnGrp(grpName2,grpName2);
3759 int newNbOfNodes=getCoords()->getNumberOfTuples();
3760 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3761 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3762 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3765 nodesDuplicated=nodeIdsToDuplicate.retn();
3766 cellsModified=cellsToModifyConn0.retn();
3767 cellsNotModified=cellsToModifyConn1.retn();
3771 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3772 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3773 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3775 * \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.
3776 * 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.
3778 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3780 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3781 std::vector<int> levs=getNonEmptyLevels();
3783 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3784 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3787 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3789 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3790 std::vector<int> code1=m->getDistributionOfTypes();
3791 end=PutInThirdComponentOfCodeOffset(code1,start);
3792 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3793 bool hasChanged=m->unPolyze();
3794 DataArrayInt *fake=0;
3795 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3796 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3798 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3801 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3802 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3804 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3805 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3806 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3807 setMeshAtLevel(*it,m);
3808 std::vector<int> code2=m->getDistributionOfTypes();
3809 end=PutInThirdComponentOfCodeOffset(code2,start);
3810 newCode.insert(newCode.end(),code2.begin(),code2.end());
3812 if(o2nCellsPart2->isIdentity())
3816 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3817 setFamilyFieldArr(*it,newFamField);
3821 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3822 setRenumFieldArr(*it,newNumField);
3827 newCode.insert(newCode.end(),code1.begin(),code1.end());
3833 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3834 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3835 o2nRenumCell=o2nRenumCellRet.retn();
3840 /*! \cond HIDDEN_ITEMS */
3841 struct MEDLoaderAccVisit1
3843 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3844 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3845 int _new_nb_of_nodes;
3850 * 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.
3851 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3852 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3853 * -1 values in returned array means that the corresponding old node is no more used.
3855 * \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
3856 * is modified in \a this.
3857 * \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
3860 DataArrayInt *MEDFileUMesh::zipCoords()
3862 const DataArrayDouble *coo(getCoords());
3864 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3865 int nbOfNodes(coo->getNumberOfTuples());
3866 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3867 std::vector<int> neLevs(getNonEmptyLevels());
3868 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3870 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3871 if(zeLev->isMeshStoredSplitByType())
3873 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3874 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3876 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3880 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3881 mesh->computeNodeIdsAlg(nodeIdsInUse);
3884 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3885 if(nbrOfNodesInUse==nbOfNodes)
3886 return 0;//no need to update _part_coords
3887 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3888 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3889 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3890 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3891 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3892 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3893 if((const DataArrayInt *)_fam_coords)
3894 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3895 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3896 if((const DataArrayInt *)_num_coords)
3897 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3898 if((const DataArrayAsciiChar *)_name_coords)
3899 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3900 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3901 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3903 if((MEDFileUMeshSplitL1*)*it)
3905 (*it)->renumberNodesInConn(ret->begin());
3906 (*it)->setCoords(_coords);
3909 // updates _part_coords
3910 const PartDefinition *pc(_part_coords);
3913 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3914 _part_coords=tmpPD->composeWith(pc);
3920 * This method performs an extrusion along a path defined by \a m1D.
3921 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3922 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3923 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3924 * This method scans all levels in \a this
3925 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3927 * \param [in] m1D - the mesh defining the extrusion path.
3928 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3929 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3931 * \sa MEDCouplingUMesh::buildExtrudedMesh
3933 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3935 if(getMeshDimension()!=2)
3936 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3937 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3938 m1D->checkCoherency();
3939 if(m1D->getMeshDimension()!=1)
3940 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3941 int nbRep(m1D->getNumberOfCells());
3942 std::vector<int> levs(getNonEmptyLevels());
3943 std::vector<std::string> grps(getGroupsNames());
3944 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3945 DataArrayDouble *coords(0);
3946 std::size_t nbOfLevsOut(levs.size()+1);
3947 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3948 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3950 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3951 item=item->clone(false);
3952 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3953 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3954 tmp->changeSpaceDimension(3+(*lev),0.);
3955 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3956 zeList.push_back(elt);
3958 coords=elt->getCoords();
3961 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3962 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3964 (*it)->setName(getName());
3965 (*it)->setCoords(coords);
3967 for(std::size_t ii=0;ii!=zeList.size();ii++)
3970 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
3973 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
3974 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
3975 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
3976 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
3977 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
3978 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
3979 std::vector<const MEDCouplingUMesh *> elts(3);
3980 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
3981 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
3982 elt->setName(getName());
3985 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
3986 ret->setMeshAtLevel(lev,elt);
3988 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
3989 endLev=endLev->clone(false); endLev->setCoords(coords);
3990 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
3991 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
3992 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
3993 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
3994 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
3995 endLev->setName(getName());
3996 ret->setMeshAtLevel(levs.back()-1,endLev);
3998 for(std::size_t ii=0;ii!=zeList.size();ii++)
4001 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
4002 std::vector< const DataArrayInt * > outGrps2;
4005 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4007 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4008 if(!grpArr->empty())
4010 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
4011 int offset0(zeList[ii]->getNumberOfCells());
4012 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4013 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4014 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4015 grpArr2->setName(oss.str());
4016 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4017 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4018 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4019 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4024 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4026 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4027 if(!grpArr->empty())
4029 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4030 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
4031 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4032 for(int iii=0;iii<nbRep;iii++)
4034 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4035 grpArrs2[iii]=grpArrs[iii];
4037 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4038 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4039 std::ostringstream grpName; grpName << *grp << "_extruded";
4040 grpArrExt->setName(grpName.str());
4041 outGrps.push_back(grpArrExt);
4042 outGrps2.push_back(grpArrExt);
4045 ret->setGroupsAtLevel(lev,outGrps2);
4047 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
4048 std::vector< const DataArrayInt * > outGrps2;
4049 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4051 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4052 if(grpArr1->empty())
4054 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
4055 std::ostringstream grpName; grpName << *grp << "_top";
4056 grpArr2->setName(grpName.str());
4057 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4058 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4059 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4061 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4066 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4067 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4068 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4070 * \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
4071 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4072 * \param [in] eps - detection threshold for coordinates.
4073 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4075 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4077 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4079 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4080 int initialNbNodes(getNumberOfNodes());
4081 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4082 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4084 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4086 DataArrayDouble *zeCoords(m0->getCoords());
4087 ret->setMeshAtLevel(0,m0);
4088 std::vector<int> levs(getNonEmptyLevels());
4089 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4092 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4093 ret->setFamilyFieldArr(0,famFieldCpy);
4095 famField=getFamilyFieldAtLevel(1);
4098 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4099 fam->fillWithZero();
4100 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4101 ret->setFamilyFieldArr(1,fam);
4103 ret->copyFamGrpMapsFrom(*this);
4104 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4105 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4109 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4110 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4111 if(m1->getMeshDimension()!=0)
4114 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4115 }//kill unused notUsed var
4116 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
4118 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4119 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4122 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4123 throw INTERP_KERNEL::Exception(oss.str().c_str());
4125 b->applyLin(1,initialNbNodes);
4126 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4127 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4128 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4129 m1->renumberNodesInConn(renum->begin());
4131 m1->setCoords(zeCoords);
4132 ret->setMeshAtLevel(*lev,m1);
4133 famField=getFamilyFieldAtLevel(*lev);
4136 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4137 ret->setFamilyFieldArr(*lev,famFieldCpy);
4144 * This method converts all quadratic cells in \a this into linear cells.
4145 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4146 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4148 * \param [in] eps - detection threshold for coordinates.
4149 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4151 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4153 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4155 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4156 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4157 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4158 m0->convertQuadraticCellsToLinear();
4160 DataArrayDouble *zeCoords(m0->getCoords());
4161 ret->setMeshAtLevel(0,m0);
4162 std::vector<int> levs(getNonEmptyLevels());
4163 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4166 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4167 ret->setFamilyFieldArr(0,famFieldCpy);
4169 famField=getFamilyFieldAtLevel(1);
4172 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
4173 ret->setFamilyFieldArr(1,fam);
4175 ret->copyFamGrpMapsFrom(*this);
4176 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4180 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4181 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4182 m1->convertQuadraticCellsToLinear();
4185 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4186 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4189 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4190 throw INTERP_KERNEL::Exception(oss.str().c_str());
4192 m1->renumberNodesInConn(b->begin());
4193 m1->setCoords(zeCoords);
4194 ret->setMeshAtLevel(*lev,m1);
4195 famField=getFamilyFieldAtLevel(*lev);
4198 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4199 ret->setFamilyFieldArr(*lev,famFieldCpy);
4205 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4207 clearNonDiscrAttributes();
4208 forceComputationOfParts();
4209 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4210 std::vector<int> layer0;
4211 layer0.push_back(_order); //0 i
4212 layer0.push_back(_iteration);//1 i
4213 layer0.push_back(getSpaceDimension());//2 i
4214 tinyDouble.push_back(_time);//0 d
4215 tinyStr.push_back(_name);//0 s
4216 tinyStr.push_back(_desc_name);//1 s
4217 for(int i=0;i<getSpaceDimension();i++)
4218 tinyStr.push_back(_coords->getInfoOnComponent(i));
4219 layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
4220 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4222 tinyStr.push_back((*it).first);
4223 layer0.push_back((*it).second);
4225 layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
4226 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4228 layer0.push_back((int)(*it0).second.size());
4229 tinyStr.push_back((*it0).first);
4230 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4231 tinyStr.push_back(*it1);
4233 // sizeof(layer0)==3+aa+1+bb layer#0
4234 bigArrayD=_coords;// 0 bd
4235 bigArraysI.push_back(_fam_coords);// 0 bi
4236 bigArraysI.push_back(_num_coords);// 1 bi
4237 const PartDefinition *pd(_part_coords);
4239 layer0.push_back(-1);
4242 std::vector<int> tmp0;
4243 pd->serialize(tmp0,bigArraysI);
4244 tinyInt.push_back(tmp0.size());
4245 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4248 std::vector<int> layer1;
4249 std::vector<int> levs(getNonEmptyLevels());
4250 layer1.push_back((int)levs.size());// 0 i <- key
4251 layer1.insert(layer1.end(),levs.begin(),levs.end());
4252 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4254 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4255 lev->serialize(layer1,bigArraysI);
4257 // put layers all together.
4258 tinyInt.push_back(layer0.size());
4259 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4260 tinyInt.push_back(layer1.size());
4261 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4264 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4265 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4267 int sz0(tinyInt[0]);
4268 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4269 int sz1(tinyInt[sz0+1]);
4270 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4272 std::reverse(layer0.begin(),layer0.end());
4273 std::reverse(layer1.begin(),layer1.end());
4274 std::reverse(tinyDouble.begin(),tinyDouble.end());
4275 std::reverse(tinyStr.begin(),tinyStr.end());
4276 std::reverse(bigArraysI.begin(),bigArraysI.end());
4278 _order=layer0.back(); layer0.pop_back();
4279 _iteration=layer0.back(); layer0.pop_back();
4280 int spaceDim(layer0.back()); layer0.pop_back();
4281 _time=tinyDouble.back(); tinyDouble.pop_back();
4282 _name=tinyStr.back(); tinyStr.pop_back();
4283 _desc_name=tinyStr.back(); tinyStr.pop_back();
4284 _coords=bigArrayD; _coords->rearrange(spaceDim);
4285 for(int i=0;i<spaceDim;i++)
4287 _coords->setInfoOnComponent(i,tinyStr.back());
4290 int nbOfFams(layer0.back()); layer0.pop_back();
4292 for(int i=0;i<nbOfFams;i++)
4294 _families[tinyStr.back()]=layer0.back();
4295 tinyStr.pop_back(); layer0.pop_back();
4297 int nbGroups(layer0.back()); layer0.pop_back();
4299 for(int i=0;i<nbGroups;i++)
4301 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4302 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4303 std::vector<std::string> fams(nbOfFamsOnGrp);
4304 for(int j=0;j<nbOfFamsOnGrp;j++)
4306 fams[j]=tinyStr.back(); tinyStr.pop_back();
4308 _groups[grpName]=fams;
4310 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4311 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4313 int isPd(layer0.back()); layer0.pop_back();
4316 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4317 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4318 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4321 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4323 int nbLevs(layer1.back()); layer1.pop_back();
4324 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4326 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4327 _ms.resize(maxLev+1);
4328 for(int i=0;i<nbLevs;i++)
4332 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4337 * Adds a group of nodes to \a this mesh.
4338 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4339 * The ids should be sorted and different each other (MED file norm).
4341 * \warning this method can alter default "FAMILLE_ZERO" family.
4342 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4344 * \throw If the node coordinates array is not set.
4345 * \throw If \a ids == \c NULL.
4346 * \throw If \a ids->getName() == "".
4347 * \throw If \a ids does not respect the MED file norm.
4348 * \throw If a group with name \a ids->getName() already exists.
4350 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4352 const DataArrayDouble *coords(_coords);
4354 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4355 int nbOfNodes(coords->getNumberOfTuples());
4356 if(!((DataArrayInt *)_fam_coords))
4357 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4359 addGroupUnderground(true,ids,_fam_coords);
4363 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4365 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4366 * The ids should be sorted and different each other (MED file norm).
4368 * \warning this method can alter default "FAMILLE_ZERO" family.
4369 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4371 * \throw If the node coordinates array is not set.
4372 * \throw If \a ids == \c NULL.
4373 * \throw If \a ids->getName() == "".
4374 * \throw If \a ids does not respect the MED file norm.
4375 * \throw If a group with name \a ids->getName() already exists.
4377 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4379 std::vector<int> levs(getNonEmptyLevelsExt());
4380 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4382 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4383 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4385 if(meshDimRelToMaxExt==1)
4386 { addNodeGroup(ids); return ; }
4387 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4388 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4389 addGroupUnderground(false,ids,fam);
4393 * Changes a name of a family specified by its id.
4394 * \param [in] id - the id of the family of interest.
4395 * \param [in] newFamName - the new family name.
4396 * \throw If no family with the given \a id exists.
4398 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4400 std::string oldName=getFamilyNameGivenId(id);
4401 _families.erase(oldName);
4402 _families[newFamName]=id;
4406 * Removes a mesh of a given dimension.
4407 * \param [in] meshDimRelToMax - the relative dimension of interest.
4408 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4410 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4412 std::vector<int> levSet=getNonEmptyLevels();
4413 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4414 if(it==levSet.end())
4415 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4416 int pos=(-meshDimRelToMax);
4421 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4422 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4423 * \param [in] m - the new mesh to set.
4424 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4426 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4427 * another node coordinates array.
4428 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4429 * to the existing meshes of other levels of \a this mesh.
4431 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4433 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4434 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4438 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4439 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4440 * \param [in] m - the new mesh to set.
4441 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4442 * writing \a this mesh in a MED file.
4443 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4445 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4446 * another node coordinates array.
4447 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4448 * to the existing meshes of other levels of \a this mesh.
4450 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4452 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4453 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4456 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4458 dealWithTinyInfo(m);
4459 std::vector<int> levSet=getNonEmptyLevels();
4460 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4462 if((DataArrayDouble *)_coords==0)
4464 DataArrayDouble *c=m->getCoords();
4469 if(m->getCoords()!=_coords)
4470 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4471 int sz=(-meshDimRelToMax)+1;
4472 if(sz>=(int)_ms.size())
4474 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4478 return _ms[-meshDimRelToMax];
4482 * This method allows to set at once the content of different levels in \a this.
4483 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4485 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4486 * \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.
4487 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4489 * \throw If \a there is a null pointer in \a ms.
4490 * \sa MEDFileUMesh::setMeshAtLevel
4492 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4496 const MEDCouplingUMesh *mRef=ms[0];
4498 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4499 std::string name(mRef->getName());
4500 const DataArrayDouble *coo(mRef->getCoords());
4503 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4505 const MEDCouplingUMesh *cur(*it);
4507 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4508 if(coo!=cur->getCoords())
4509 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4510 int mdim=cur->getMeshDimension();
4511 zeDim=std::max(zeDim,mdim);
4512 if(s.find(mdim)!=s.end())
4513 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4515 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4517 int mdim=(*it)->getMeshDimension();
4518 setName((*it)->getName());
4519 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4525 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4526 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4527 * The given meshes must share the same node coordinates array.
4528 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4529 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4530 * create in \a this mesh.
4531 * \throw If \a ms is empty.
4532 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4533 * to the existing meshes of other levels of \a this mesh.
4534 * \throw If the meshes in \a ms do not share the same node coordinates array.
4535 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4536 * of the given meshes.
4537 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4538 * \throw If names of some meshes in \a ms are equal.
4539 * \throw If \a ms includes a mesh with an empty name.
4541 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4544 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4545 int sz=(-meshDimRelToMax)+1;
4546 if(sz>=(int)_ms.size())
4548 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4549 DataArrayDouble *coo=checkMultiMesh(ms);
4550 if((DataArrayDouble *)_coords==0)
4556 if((DataArrayDouble *)_coords!=coo)
4557 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4558 std::vector<DataArrayInt *> corr;
4559 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4560 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4561 setMeshAtLevel(meshDimRelToMax,m,renum);
4562 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4563 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4567 * Creates groups at a given level in \a this mesh from a sequence of
4568 * meshes each representing a group.
4569 * The given meshes must share the same node coordinates array.
4570 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4571 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4572 * create in \a this mesh.
4573 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4575 * \throw If \a ms is empty.
4576 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4577 * to the existing meshes of other levels of \a this mesh.
4578 * \throw If the meshes in \a ms do not share the same node coordinates array.
4579 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4580 * of the given meshes.
4581 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4582 * \throw If names of some meshes in \a ms are equal.
4583 * \throw If \a ms includes a mesh with an empty name.
4585 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4588 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4589 int sz=(-meshDimRelToMax)+1;
4590 if(sz>=(int)_ms.size())
4592 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4593 DataArrayDouble *coo=checkMultiMesh(ms);
4594 if((DataArrayDouble *)_coords==0)
4600 if((DataArrayDouble *)_coords!=coo)
4601 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4602 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4603 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4605 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4607 DataArrayInt *arr=0;
4608 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4612 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4613 throw INTERP_KERNEL::Exception(oss.str().c_str());
4616 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4617 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4620 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4622 const DataArrayDouble *ret=ms[0]->getCoords();
4623 int mdim=ms[0]->getMeshDimension();
4624 for(unsigned int i=1;i<ms.size();i++)
4626 ms[i]->checkCoherency();
4627 if(ms[i]->getCoords()!=ret)
4628 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4629 if(ms[i]->getMeshDimension()!=mdim)
4630 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4632 return const_cast<DataArrayDouble *>(ret);
4636 * Sets the family field of a given relative dimension.
4637 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4638 * the family field is set.
4639 * \param [in] famArr - the array of the family field.
4640 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4641 * \throw If \a famArr has an invalid size.
4643 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4645 if(meshDimRelToMaxExt==1)
4652 DataArrayDouble *coo(_coords);
4654 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4655 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4660 if(meshDimRelToMaxExt>1)
4661 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4662 int traducedRk=-meshDimRelToMaxExt;
4663 if(traducedRk>=(int)_ms.size())
4664 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4665 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4666 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4667 return _ms[traducedRk]->setFamilyArr(famArr);
4671 * Sets the optional numbers of mesh entities of a given dimension.
4672 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4673 * \param [in] renumArr - the array of the numbers.
4674 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4675 * \throw If \a renumArr has an invalid size.
4677 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4679 if(meshDimRelToMaxExt==1)
4687 DataArrayDouble *coo(_coords);
4689 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4690 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4691 renumArr->incrRef();
4692 _num_coords=renumArr;
4696 if(meshDimRelToMaxExt>1)
4697 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4698 int traducedRk=-meshDimRelToMaxExt;
4699 if(traducedRk>=(int)_ms.size())
4700 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4701 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4702 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4703 return _ms[traducedRk]->setRenumArr(renumArr);
4707 * Sets the optional names of mesh entities of a given dimension.
4708 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4709 * \param [in] nameArr - the array of the names.
4710 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4711 * \throw If \a nameArr has an invalid size.
4713 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4715 if(meshDimRelToMaxExt==1)
4722 DataArrayDouble *coo(_coords);
4724 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4725 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4727 _name_coords=nameArr;
4730 if(meshDimRelToMaxExt>1)
4731 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4732 int traducedRk=-meshDimRelToMaxExt;
4733 if(traducedRk>=(int)_ms.size())
4734 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4735 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4736 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4737 return _ms[traducedRk]->setNameArr(nameArr);
4740 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4742 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4743 if((const MEDFileUMeshSplitL1 *)(*it))
4744 (*it)->synchronizeTinyInfo(*this);
4748 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4750 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4752 DataArrayInt *arr=_fam_coords;
4754 arr->changeValue(oldId,newId);
4755 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4757 MEDFileUMeshSplitL1 *sp=(*it);
4760 sp->changeFamilyIdArr(oldId,newId);
4765 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4767 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4768 const DataArrayInt *da(_fam_coords);
4770 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4771 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4773 const MEDFileUMeshSplitL1 *elt(*it);
4776 da=elt->getFamilyField();
4778 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4784 void MEDFileUMesh::computeRevNum() const
4786 if((const DataArrayInt *)_num_coords)
4789 int maxValue=_num_coords->getMaxValue(pos);
4790 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4794 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4796 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4799 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4801 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4802 ret.push_back((const DataArrayInt *)_fam_nodes);
4803 ret.push_back((const DataArrayInt *)_num_nodes);
4804 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4805 ret.push_back((const DataArrayInt *)_fam_cells);
4806 ret.push_back((const DataArrayInt *)_num_cells);
4807 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4808 ret.push_back((const DataArrayInt *)_fam_faces);
4809 ret.push_back((const DataArrayInt *)_num_faces);
4810 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4811 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4812 ret.push_back((const DataArrayInt *)_rev_num_cells);
4813 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4817 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4819 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4820 if((const DataArrayInt *)_fam_nodes)
4822 int val=_fam_nodes->getMaxValue(tmp);
4823 ret=std::max(ret,std::abs(val));
4825 if((const DataArrayInt *)_fam_cells)
4827 int val=_fam_cells->getMaxValue(tmp);
4828 ret=std::max(ret,std::abs(val));
4830 if((const DataArrayInt *)_fam_faces)
4832 int val=_fam_faces->getMaxValue(tmp);
4833 ret=std::max(ret,std::abs(val));
4838 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4840 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4841 if((const DataArrayInt *)_fam_nodes)
4843 int val=_fam_nodes->getMaxValue(tmp);
4844 ret=std::max(ret,val);
4846 if((const DataArrayInt *)_fam_cells)
4848 int val=_fam_cells->getMaxValue(tmp);
4849 ret=std::max(ret,val);
4851 if((const DataArrayInt *)_fam_faces)
4853 int val=_fam_faces->getMaxValue(tmp);
4854 ret=std::max(ret,val);
4859 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4861 int ret=std::numeric_limits<int>::max(),tmp=-1;
4862 if((const DataArrayInt *)_fam_nodes)
4864 int val=_fam_nodes->getMinValue(tmp);
4865 ret=std::min(ret,val);
4867 if((const DataArrayInt *)_fam_cells)
4869 int val=_fam_cells->getMinValue(tmp);
4870 ret=std::min(ret,val);
4872 if((const DataArrayInt *)_fam_faces)
4874 int val=_fam_faces->getMinValue(tmp);
4875 ret=std::min(ret,val);
4880 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4882 if(!MEDFileMesh::isEqual(other,eps,what))
4884 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4887 what="Mesh types differ ! This is structured and other is NOT !";
4890 const DataArrayInt *famc1=_fam_nodes;
4891 const DataArrayInt *famc2=otherC->_fam_nodes;
4892 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4894 what="Mismatch of families arr on nodes ! One is defined and not other !";
4899 bool ret=famc1->isEqual(*famc2);
4902 what="Families arr on nodes differ !";
4907 famc2=otherC->_fam_cells;
4908 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4910 what="Mismatch of families arr on cells ! One is defined and not other !";
4915 bool ret=famc1->isEqual(*famc2);
4918 what="Families arr on cells differ !";
4923 famc2=otherC->_fam_faces;
4924 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4926 what="Mismatch of families arr on faces ! One is defined and not other !";
4931 bool ret=famc1->isEqual(*famc2);
4934 what="Families arr on faces differ !";
4939 famc2=otherC->_num_nodes;
4940 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4942 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4947 bool ret=famc1->isEqual(*famc2);
4950 what="Numbering arr on nodes differ !";
4955 famc2=otherC->_num_cells;
4956 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4958 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4963 bool ret=famc1->isEqual(*famc2);
4966 what="Numbering arr on cells differ !";
4971 famc2=otherC->_num_faces;
4972 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4974 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4979 bool ret=famc1->isEqual(*famc2);
4982 what="Numbering arr on faces differ !";
4986 const DataArrayAsciiChar *d1=_names_cells;
4987 const DataArrayAsciiChar *d2=otherC->_names_cells;
4988 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4990 what="Mismatch of naming arr on cells ! One is defined and not other !";
4995 bool ret=d1->isEqual(*d2);
4998 what="Naming arr on cells differ !";
5003 d2=otherC->_names_faces;
5004 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5006 what="Mismatch of naming arr on faces ! One is defined and not other !";
5011 bool ret=d1->isEqual(*d2);
5014 what="Naming arr on faces differ !";
5019 d2=otherC->_names_nodes;
5020 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5022 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5027 bool ret=d1->isEqual(*d2);
5030 what="Naming arr on nodes differ !";
5037 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5039 MEDFileMesh::clearNonDiscrAttributes();
5040 const DataArrayInt *tmp=_fam_nodes;
5042 (const_cast<DataArrayInt *>(tmp))->setName("");
5045 (const_cast<DataArrayInt *>(tmp))->setName("");
5048 (const_cast<DataArrayInt *>(tmp))->setName("");
5051 (const_cast<DataArrayInt *>(tmp))->setName("");
5054 (const_cast<DataArrayInt *>(tmp))->setName("");
5057 (const_cast<DataArrayInt *>(tmp))->setName("");
5061 * Returns ids of mesh entities contained in given families of a given dimension.
5062 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5064 * \param [in] fams - the names of the families of interest.
5065 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5066 * returned instead of ids.
5067 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5068 * numbers, if available and required, of mesh entities of the families. The caller
5069 * is to delete this array using decrRef() as it is no more needed.
5070 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5072 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5074 std::vector<int> famIds(getFamiliesIds(fams));
5075 switch(meshDimRelToMaxExt)
5079 if((const DataArrayInt *)_fam_nodes)
5081 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5083 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5085 da=_fam_nodes->getIdsEqualList(0,0);
5087 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5092 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5097 if((const DataArrayInt *)_fam_cells)
5099 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5101 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5103 da=_fam_cells->getIdsEqualList(0,0);
5105 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5110 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5115 if((const DataArrayInt *)_fam_faces)
5117 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5119 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5121 da=_fam_faces->getIdsEqualList(0,0);
5123 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5128 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5132 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5134 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5138 * Sets the family field of a given relative dimension.
5139 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5140 * the family field is set.
5141 * \param [in] famArr - the array of the family field.
5142 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5143 * \throw If \a famArr has an invalid size.
5144 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5146 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5148 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5150 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5151 switch(meshDimRelToMaxExt)
5155 int nbCells=mesh->getNumberOfCells();
5156 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5162 int nbNodes=mesh->getNumberOfNodes();
5163 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5169 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5170 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5175 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5182 * Sets the optional numbers of mesh entities of a given dimension.
5183 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5184 * \param [in] renumArr - the array of the numbers.
5185 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5186 * \throw If \a renumArr has an invalid size.
5187 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5189 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5191 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5193 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5194 switch(meshDimRelToMaxExt)
5198 int nbCells=mesh->getNumberOfCells();
5199 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5200 _num_cells=renumArr;
5205 int nbNodes=mesh->getNumberOfNodes();
5206 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5207 _num_nodes=renumArr;
5212 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5213 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5214 _num_faces=renumArr;
5218 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5221 renumArr->incrRef();
5225 * Sets the optional names of mesh entities of a given dimension.
5226 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5227 * \param [in] nameArr - the array of the names.
5228 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5229 * \throw If \a nameArr has an invalid size.
5231 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5233 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5235 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5236 switch(meshDimRelToMaxExt)
5240 int nbCells=mesh->getNumberOfCells();
5241 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5242 _names_cells=nameArr;
5247 int nbNodes=mesh->getNumberOfNodes();
5248 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5249 _names_nodes=nameArr;
5254 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5255 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5256 _names_cells=nameArr;
5259 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5266 * Adds a group of nodes to \a this mesh.
5267 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5268 * The ids should be sorted and different each other (MED file norm).
5270 * \warning this method can alter default "FAMILLE_ZERO" family.
5271 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5273 * \throw If the node coordinates array is not set.
5274 * \throw If \a ids == \c NULL.
5275 * \throw If \a ids->getName() == "".
5276 * \throw If \a ids does not respect the MED file norm.
5277 * \throw If a group with name \a ids->getName() already exists.
5279 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5285 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5287 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5288 * The ids should be sorted and different each other (MED file norm).
5290 * \warning this method can alter default "FAMILLE_ZERO" family.
5291 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5293 * \throw If the node coordinates array is not set.
5294 * \throw If \a ids == \c NULL.
5295 * \throw If \a ids->getName() == "".
5296 * \throw If \a ids does not respect the MED file norm.
5297 * \throw If a group with name \a ids->getName() already exists.
5299 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5301 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5302 addGroupUnderground(false,ids,fam);
5307 * Returns the family field for mesh entities of a given dimension.
5308 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5309 * \return const DataArrayInt * - the family field. It is an array of ids of families
5310 * each mesh entity belongs to. It can be \c NULL.
5311 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5313 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5315 switch(meshDimRelToMaxExt)
5324 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5329 * Returns the family field for mesh entities of a given dimension.
5330 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5331 * \return const DataArrayInt * - the family field. It is an array of ids of families
5332 * each mesh entity belongs to. It can be \c NULL.
5333 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5335 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5337 switch(meshDimRelToMaxExt)
5346 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5351 * Returns the optional numbers of mesh entities of a given dimension.
5352 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5353 * \return const DataArrayInt * - the array of the entity numbers.
5354 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5355 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5357 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5359 switch(meshDimRelToMaxExt)
5368 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5373 * Returns the optional numbers of mesh entities of a given dimension transformed using
5374 * DataArrayInt::invertArrayN2O2O2N().
5375 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5376 * \return const DataArrayInt * - the array of the entity numbers transformed using
5377 * DataArrayInt::invertArrayN2O2O2N().
5378 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5379 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5381 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5383 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5384 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5385 if(meshDimRelToMaxExt==0)
5387 if((const DataArrayInt *)_num_cells)
5390 int maxValue=_num_cells->getMaxValue(pos);
5391 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5392 return _rev_num_cells;
5395 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5399 if((const DataArrayInt *)_num_nodes)
5402 int maxValue=_num_nodes->getMaxValue(pos);
5403 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5404 return _rev_num_nodes;
5407 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5411 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5413 switch(meshDimRelToMaxExt)
5416 return _names_cells;
5418 return _names_nodes;
5420 return _names_faces;
5422 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5427 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5428 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5430 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5432 std::vector<int> ret(1);
5437 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5438 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5440 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5442 std::vector<int> ret(2);
5448 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5450 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5452 std::vector<int> ret;
5453 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5464 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5466 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5468 std::vector<int> ret;
5469 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5480 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5482 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5484 std::vector<int> ret;
5485 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5496 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5498 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5500 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5504 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5506 DataArrayInt *arr=_fam_nodes;
5508 arr->changeValue(oldId,newId);
5511 arr->changeValue(oldId,newId);
5514 arr->changeValue(oldId,newId);
5517 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5519 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
5520 const DataArrayInt *da(_fam_nodes);
5522 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5525 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5528 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5532 void MEDFileStructuredMesh::deepCpyAttributes()
5534 if((const DataArrayInt*)_fam_nodes)
5535 _fam_nodes=_fam_nodes->deepCpy();
5536 if((const DataArrayInt*)_num_nodes)
5537 _num_nodes=_num_nodes->deepCpy();
5538 if((const DataArrayAsciiChar*)_names_nodes)
5539 _names_nodes=_names_nodes->deepCpy();
5540 if((const DataArrayInt*)_fam_cells)
5541 _fam_cells=_fam_cells->deepCpy();
5542 if((const DataArrayInt*)_num_cells)
5543 _num_cells=_num_cells->deepCpy();
5544 if((const DataArrayAsciiChar*)_names_cells)
5545 _names_cells=_names_cells->deepCpy();
5546 if((const DataArrayInt*)_fam_faces)
5547 _fam_faces=_fam_faces->deepCpy();
5548 if((const DataArrayInt*)_num_faces)
5549 _num_faces=_num_faces->deepCpy();
5550 if((const DataArrayAsciiChar*)_names_faces)
5551 _names_faces=_names_faces->deepCpy();
5552 if((const DataArrayInt*)_rev_num_nodes)
5553 _rev_num_nodes=_rev_num_nodes->deepCpy();
5554 if((const DataArrayInt*)_rev_num_cells)
5555 _rev_num_cells=_rev_num_cells->deepCpy();
5559 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5561 * \return a pointer to cartesian mesh that need to be managed by the caller.
5562 * \warning the returned pointer has to be managed by the caller.
5566 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5567 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5568 * \param [in] renum - it must be \c false.
5569 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5570 * delete using decrRef() as it is no more needed.
5572 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
5575 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5576 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5577 switch(meshDimRelToMax)
5583 return const_cast<MEDCouplingStructuredMesh *>(m);
5588 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5589 buildMinusOneImplicitPartIfNeeded();
5590 MEDCouplingMesh *ret(_faces_if_necessary);
5596 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5601 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5602 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5603 * \return int - the number of entities.
5604 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5606 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5608 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5610 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5611 switch(meshDimRelToMaxExt)
5614 return cmesh->getNumberOfCells();
5616 return cmesh->getNumberOfNodes();
5618 return cmesh->getNumberOfCellsOfSubLevelMesh();
5620 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5624 int MEDFileStructuredMesh::getNumberOfNodes() const
5626 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5628 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5629 return cmesh->getNumberOfNodes();
5632 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5634 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5636 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5637 switch(meshDimRelToMaxExt)
5640 return cmesh->getNumberOfCells();
5642 return cmesh->getNumberOfCellsOfSubLevelMesh();
5644 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5648 bool MEDFileStructuredMesh::hasImplicitPart() const
5654 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5656 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5658 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5659 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5662 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5663 if(cm.getReverseExtrudedType()!=gt)
5664 throw INTERP_KERNEL::Exception(MSG);
5665 buildImplicitPart();
5666 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5670 if(gt!=zeFaceMesh->getCellModelEnum())
5671 throw INTERP_KERNEL::Exception(MSG);
5672 return zeFaceMesh->getNumberOfCells();
5676 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5678 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5680 buildImplicitPart();
5683 void MEDFileStructuredMesh::buildImplicitPart() const
5685 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5687 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5688 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5691 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5693 _faces_if_necessary=0;
5697 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5698 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5700 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5702 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5704 return _faces_if_necessary;
5707 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5709 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5711 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5712 switch(meshDimRelToMax)
5716 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5721 int mdim(cmesh->getMeshDimension());
5723 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5724 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5728 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5732 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
5734 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5737 return getNumberOfCellsAtLevel(0);
5740 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5742 if(st.getNumberOfItems()!=1)
5743 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 !");
5744 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5745 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5746 if(getNumberOfNodes()!=(int)nodesFetched.size())
5747 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5748 if(st[0].getPflName().empty())
5750 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5753 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5754 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5755 int sz(nodesFetched.size());
5756 for(const int *work=arr->begin();work!=arr->end();work++)
5758 std::vector<int> conn;
5759 cmesh->getNodeIdsOfCell(*work,conn);
5760 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5761 if(*it>=0 && *it<sz)
5762 nodesFetched[*it]=true;
5764 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5768 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5770 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5774 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5775 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5777 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5778 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5780 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5783 if(!mrs || mrs->isCellFamilyFieldReading())
5785 famCells=DataArrayInt::New();
5786 famCells->alloc(nbOfElt,1);
5787 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
5790 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5793 if(!mrs || mrs->isCellNumFieldReading())
5795 numCells=DataArrayInt::New();
5796 numCells->alloc(nbOfElt,1);
5797 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
5800 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5803 if(!mrs || mrs->isCellNameFieldReading())
5805 namesCells=DataArrayAsciiChar::New();
5806 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5807 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
5808 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5813 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5815 setName(strm->getName());
5816 setDescription(strm->getDescription());
5817 setUnivName(strm->getUnivName());
5818 setIteration(strm->getIteration());
5819 setOrder(strm->getOrder());
5820 setTimeValue(strm->getTime());
5821 setTimeUnit(strm->getTimeUnit());
5822 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5823 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5824 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
5827 if(!mrs || mrs->isNodeFamilyFieldReading())
5829 int nbNodes(getNumberOfNodes());
5831 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5832 _fam_nodes=DataArrayInt::New();
5833 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5834 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...
5835 _fam_nodes->fillWithZero();
5836 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
5839 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5842 if(!mrs || mrs->isNodeNumFieldReading())
5844 _num_nodes=DataArrayInt::New();
5845 _num_nodes->alloc(nbOfElt,1);
5846 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
5849 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5852 if(!mrs || mrs->isNodeNameFieldReading())
5854 _names_nodes=DataArrayAsciiChar::New();
5855 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5856 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
5857 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5860 int meshDim(getStructuredMesh()->getMeshDimension());
5861 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5863 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5866 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5868 int meshDim(getStructuredMesh()->getMeshDimension());
5869 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5871 if((const DataArrayInt *)_fam_cells)
5872 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
5873 if((const DataArrayInt *)_fam_faces)
5874 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
5875 if((const DataArrayInt *)_fam_nodes)
5876 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
5877 if((const DataArrayInt *)_num_cells)
5878 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
5879 if((const DataArrayInt *)_num_faces)
5880 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
5881 if((const DataArrayInt *)_num_nodes)
5882 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
5883 if((const DataArrayAsciiChar *)_names_cells)
5885 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5887 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5888 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5889 throw INTERP_KERNEL::Exception(oss.str().c_str());
5891 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
5893 if((const DataArrayAsciiChar *)_names_faces)
5895 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5897 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5898 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5899 throw INTERP_KERNEL::Exception(oss.str().c_str());
5901 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
5903 if((const DataArrayAsciiChar *)_names_nodes)
5905 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5907 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5908 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5909 throw INTERP_KERNEL::Exception(oss.str().c_str());
5911 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
5914 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5918 * Returns an empty instance of MEDFileCMesh.
5919 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5920 * mesh using decrRef() as it is no more needed.
5922 MEDFileCMesh *MEDFileCMesh::New()
5924 return new MEDFileCMesh;
5928 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5929 * file. The first mesh in the file is loaded.
5930 * \param [in] fileName - the name of MED file to read.
5931 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5932 * mesh using decrRef() as it is no more needed.
5933 * \throw If the file is not readable.
5934 * \throw If there is no meshes in the file.
5935 * \throw If the mesh in the file is not a Cartesian one.
5937 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5939 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5942 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5943 throw INTERP_KERNEL::Exception(oss.str().c_str());
5945 MEDFileUtilities::CheckFileForRead(fileName);
5946 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5948 ParaMEDMEM::MEDCouplingMeshType meshType;
5950 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5951 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5955 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5956 * file. The mesh to load is specified by its name and numbers of a time step and an
5958 * \param [in] fileName - the name of MED file to read.
5959 * \param [in] mName - the name of the mesh to read.
5960 * \param [in] dt - the number of a time step.
5961 * \param [in] it - the number of an iteration.
5962 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5963 * mesh using decrRef() as it is no more needed.
5964 * \throw If the file is not readable.
5965 * \throw If there is no mesh with given attributes in the file.
5966 * \throw If the mesh in the file is not a Cartesian one.
5968 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5970 MEDFileUtilities::CheckFileForRead(fileName);
5971 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5972 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5975 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5977 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5980 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5982 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5983 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5988 * Returns the dimension on cells in \a this mesh.
5989 * \return int - the mesh dimension.
5990 * \throw If there are no cells in this mesh.
5992 int MEDFileCMesh::getMeshDimension() const
5994 if(!((const MEDCouplingCMesh*)_cmesh))
5995 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5996 return _cmesh->getMeshDimension();
6000 * Returns the dimension on nodes in \a this mesh.
6001 * \return int - the space dimension.
6002 * \throw If there are no cells in this mesh.
6004 int MEDFileCMesh::getSpaceDimension() const
6006 if(!((const MEDCouplingCMesh*)_cmesh))
6007 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6008 return _cmesh->getSpaceDimension();
6012 * Returns a string describing \a this mesh.
6013 * \return std::string - the mesh information string.
6015 std::string MEDFileCMesh::simpleRepr() const
6017 return MEDFileStructuredMesh::simpleRepr();
6021 * Returns a full textual description of \a this mesh.
6022 * \return std::string - the string holding the mesh description.
6024 std::string MEDFileCMesh::advancedRepr() const
6026 return simpleRepr();
6029 MEDFileMesh *MEDFileCMesh::shallowCpy() const
6031 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
6035 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6037 return new MEDFileCMesh;
6040 MEDFileMesh *MEDFileCMesh::deepCpy() const
6042 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
6043 ret->deepCpyEquivalences(*this);
6044 if((const MEDCouplingCMesh*)_cmesh)
6045 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
6046 ret->deepCpyAttributes();
6051 * Checks if \a this and another mesh are equal.
6052 * \param [in] other - the mesh to compare with.
6053 * \param [in] eps - a precision used to compare real values.
6054 * \param [in,out] what - the string returning description of unequal data.
6055 * \return bool - \c true if the meshes are equal, \c false, else.
6057 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6059 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6061 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6064 what="Mesh types differ ! This is cartesian and other is NOT !";
6067 clearNonDiscrAttributes();
6068 otherC->clearNonDiscrAttributes();
6069 const MEDCouplingCMesh *coo1=_cmesh;
6070 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6071 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6073 what="Mismatch of cartesian meshes ! One is defined and not other !";
6078 bool ret=coo1->isEqual(coo2,eps);
6081 what="cartesian meshes differ !";
6089 * Clears redundant attributes of incorporated data arrays.
6091 void MEDFileCMesh::clearNonDiscrAttributes() const
6093 MEDFileStructuredMesh::clearNonDiscrAttributes();
6094 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6097 MEDFileCMesh::MEDFileCMesh()
6101 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6104 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6106 catch(INTERP_KERNEL::Exception& e)
6111 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6113 ParaMEDMEM::MEDCouplingMeshType meshType;
6116 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6117 if(meshType!=CARTESIAN)
6119 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6120 throw INTERP_KERNEL::Exception(oss.str().c_str());
6122 MEDFileCMeshL2 loaderl2;
6123 loaderl2.loadAll(fid,mid,mName,dt,it);
6124 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6127 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6131 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6132 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6134 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6136 synchronizeTinyInfoOnLeaves();
6140 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6142 synchronizeTinyInfoOnLeaves();
6147 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6148 * \param [in] m - the new MEDCouplingCMesh to refer to.
6149 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6152 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6154 dealWithTinyInfo(m);
6160 void MEDFileCMesh::writeLL(med_idt fid) const
6162 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6163 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6164 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6165 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6166 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6167 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6168 int spaceDim(_cmesh->getSpaceDimension());
6169 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6170 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6171 for(int i=0;i<spaceDim;i++)
6173 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6175 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6176 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
6177 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
6179 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
6181 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6182 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID));
6183 for(int i=0;i<spaceDim;i++)
6185 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6186 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6189 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6190 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6193 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6195 const MEDCouplingCMesh *cmesh=_cmesh;
6198 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6199 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6200 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6201 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6204 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6206 return new MEDFileCurveLinearMesh;
6209 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6211 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6214 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6215 throw INTERP_KERNEL::Exception(oss.str().c_str());
6217 MEDFileUtilities::CheckFileForRead(fileName);
6218 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6220 ParaMEDMEM::MEDCouplingMeshType meshType;
6222 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6223 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6226 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6228 MEDFileUtilities::CheckFileForRead(fileName);
6229 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6230 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6233 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6235 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6238 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6240 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6241 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6245 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6247 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6251 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6253 return new MEDFileCurveLinearMesh;
6256 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
6258 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6259 ret->deepCpyEquivalences(*this);
6260 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6261 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
6262 ret->deepCpyAttributes();
6266 int MEDFileCurveLinearMesh::getMeshDimension() const
6268 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6269 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6270 return _clmesh->getMeshDimension();
6273 std::string MEDFileCurveLinearMesh::simpleRepr() const
6275 return MEDFileStructuredMesh::simpleRepr();
6278 std::string MEDFileCurveLinearMesh::advancedRepr() const
6280 return simpleRepr();
6283 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6285 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6287 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6290 what="Mesh types differ ! This is curve linear and other is NOT !";
6293 clearNonDiscrAttributes();
6294 otherC->clearNonDiscrAttributes();
6295 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6296 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6297 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6299 what="Mismatch of curve linear meshes ! One is defined and not other !";
6304 bool ret=coo1->isEqual(coo2,eps);
6307 what="curve linear meshes differ !";
6314 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6316 MEDFileStructuredMesh::clearNonDiscrAttributes();
6317 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6320 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6322 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6325 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6326 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6327 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6328 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6331 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6333 synchronizeTinyInfoOnLeaves();
6337 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6339 dealWithTinyInfo(m);
6345 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6347 synchronizeTinyInfoOnLeaves();
6351 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6355 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6358 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6360 catch(INTERP_KERNEL::Exception& e)
6365 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6367 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6368 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6369 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6370 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6371 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6372 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6373 int spaceDim=_clmesh->getSpaceDimension();
6374 int meshDim=_clmesh->getMeshDimension();
6375 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6376 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6377 const DataArrayDouble *coords=_clmesh->getCoords();
6379 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6380 for(int i=0;i<spaceDim;i++)
6382 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6384 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6385 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
6386 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
6388 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
6390 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6391 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6392 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6393 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6395 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6397 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6398 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6401 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6403 ParaMEDMEM::MEDCouplingMeshType meshType;
6406 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6407 if(meshType!=CURVE_LINEAR)
6409 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6410 throw INTERP_KERNEL::Exception(oss.str().c_str());
6412 MEDFileCLMeshL2 loaderl2;
6413 loaderl2.loadAll(fid,mid,mName,dt,it);
6414 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6417 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6420 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6422 return new MEDFileMeshMultiTS;
6425 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6427 return new MEDFileMeshMultiTS(fileName);
6430 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6432 return new MEDFileMeshMultiTS(fileName,mName);
6435 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6437 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6438 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6440 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6441 if((const MEDFileMesh *)*it)
6442 meshOneTs[i]=(*it)->deepCpy();
6443 ret->_mesh_one_ts=meshOneTs;
6447 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6449 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6452 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6454 std::vector<const BigMemoryObject *> ret;
6455 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6456 ret.push_back((const MEDFileMesh *)*it);
6460 std::string MEDFileMeshMultiTS::getName() const
6462 if(_mesh_one_ts.empty())
6463 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6464 return _mesh_one_ts[0]->getName();
6467 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6469 std::string oldName(getName());
6470 std::vector< std::pair<std::string,std::string> > v(1);
6471 v[0].first=oldName; v[0].second=newMeshName;
6475 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6478 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6480 MEDFileMesh *cur(*it);
6482 ret=cur->changeNames(modifTab) || ret;
6487 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6489 if(_mesh_one_ts.empty())
6490 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6491 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6494 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6497 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6498 _mesh_one_ts.resize(1);
6499 mesh1TimeStep->incrRef();
6500 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6501 _mesh_one_ts[0]=mesh1TimeStep;
6504 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
6506 if ( MEDFileMesh* m = getOneTimeStep() )
6507 return m->getJoints();
6512 * \brief Set Joints that are common to all time-stamps
6514 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
6516 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6518 (*it)->setJoints( joints );
6522 void MEDFileMeshMultiTS::write(med_idt fid) const
6524 MEDFileJoints *joints(getJoints());
6525 bool jointsWritten(false);
6527 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6529 if ( jointsWritten )
6530 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
6532 jointsWritten = true;
6534 (*it)->copyOptionsFrom(*this);
6538 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
6541 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6543 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6544 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6545 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6546 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6550 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6552 MEDFileJoints* joints = 0;
6553 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
6555 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
6556 joints = getOneTimeStep()->getJoints();
6559 _mesh_one_ts.clear(); //for the moment to be improved
6560 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
6563 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6567 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6570 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6573 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6574 throw INTERP_KERNEL::Exception(oss.str().c_str());
6576 MEDFileUtilities::CheckFileForRead(fileName);
6577 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6579 ParaMEDMEM::MEDCouplingMeshType meshType;
6581 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6582 loadFromFile(fileName,ms.front());
6584 catch(INTERP_KERNEL::Exception& e)
6589 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6592 loadFromFile(fileName,mName);
6594 catch(INTERP_KERNEL::Exception& e)
6599 MEDFileMeshes *MEDFileMeshes::New()
6601 return new MEDFileMeshes;
6604 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6606 return new MEDFileMeshes(fileName);
6609 void MEDFileMeshes::write(med_idt fid) const
6612 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6614 (*it)->copyOptionsFrom(*this);
6619 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6621 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6622 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6623 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6624 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6629 int MEDFileMeshes::getNumberOfMeshes() const
6631 return _meshes.size();
6634 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6636 return new MEDFileMeshesIterator(this);
6639 /** Return a borrowed reference (caller is not responsible) */
6640 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6642 if(i<0 || i>=(int)_meshes.size())
6644 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6645 throw INTERP_KERNEL::Exception(oss.str().c_str());
6647 return _meshes[i]->getOneTimeStep();
6650 /** Return a borrowed reference (caller is not responsible) */
6651 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6653 std::vector<std::string> ms=getMeshesNames();
6654 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6657 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6658 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6659 throw INTERP_KERNEL::Exception(oss.str().c_str());
6661 return getMeshAtPos((int)std::distance(ms.begin(),it));
6664 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6666 std::vector<std::string> ret(_meshes.size());
6668 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6670 const MEDFileMeshMultiTS *f=(*it);
6673 ret[i]=f->getName();
6677 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6678 throw INTERP_KERNEL::Exception(oss.str().c_str());
6683 /*const MEDFileJoints* MEDFileMeshes::getJoints() const
6685 const MEDFileJoints *ret=_joints;
6688 std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !";
6689 throw INTERP_KERNEL::Exception(oss.str().c_str());
6694 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6697 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6699 MEDFileMeshMultiTS *cur(*it);
6701 ret=cur->changeNames(modifTab) || ret;
6706 void MEDFileMeshes::resize(int newSize)
6708 _meshes.resize(newSize);
6711 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6714 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6715 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6716 elt->setOneTimeStep(mesh);
6717 _meshes.push_back(elt);
6720 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6723 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6724 if(i>=(int)_meshes.size())
6725 _meshes.resize(i+1);
6726 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6727 elt->setOneTimeStep(mesh);
6731 void MEDFileMeshes::destroyMeshAtPos(int i)
6733 if(i<0 || i>=(int)_meshes.size())
6735 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6736 throw INTERP_KERNEL::Exception(oss.str().c_str());
6738 _meshes.erase(_meshes.begin()+i);
6741 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6743 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6745 _meshes.resize(ms.size());
6746 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6747 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6750 MEDFileMeshes::MEDFileMeshes()
6754 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6757 loadFromFile(fileName);
6759 catch(INTERP_KERNEL::Exception& /*e*/)
6763 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6765 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6767 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6768 if((const MEDFileMeshMultiTS *)*it)
6769 meshes[i]=(*it)->deepCpy();
6770 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6771 ret->_meshes=meshes;
6775 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6777 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6780 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6782 std::vector<const BigMemoryObject *> ret;
6783 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6784 ret.push_back((const MEDFileMeshMultiTS *)*it);
6788 std::string MEDFileMeshes::simpleRepr() const
6790 std::ostringstream oss;
6791 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6792 simpleReprWithoutHeader(oss);
6796 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6798 int nbOfMeshes=getNumberOfMeshes();
6799 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6800 std::vector<std::string> mns=getMeshesNames();
6801 for(int i=0;i<nbOfMeshes;i++)
6802 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6805 void MEDFileMeshes::checkCoherency() const
6807 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6809 std::set<std::string> s;
6810 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6812 const MEDFileMeshMultiTS *elt=(*it);
6815 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6816 throw INTERP_KERNEL::Exception(oss.str().c_str());
6818 std::size_t sz=s.size();
6819 s.insert(std::string((*it)->getName()));
6822 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6823 throw INTERP_KERNEL::Exception(oss.str().c_str());
6828 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6833 _nb_iter=ms->getNumberOfMeshes();
6837 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6841 MEDFileMesh *MEDFileMeshesIterator::nextt()
6843 if(_iter_id<_nb_iter)
6845 MEDFileMeshes *ms(_ms);
6847 return ms->getMeshAtPos(_iter_id++);