1 // Copyright (C) 2007-2014 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 "MEDLoaderBase.hxx"
28 #include "MEDCouplingUMesh.hxx"
30 #include "InterpKernelAutoPtr.hxx"
35 extern med_geometry_type typmai3[34];
37 using namespace ParaMEDMEM;
39 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
41 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
45 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
47 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
48 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
50 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
51 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
52 ret+=(*it2).capacity();
54 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
55 ret+=(*it).first.capacity()+sizeof(int);
59 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildren() const
61 return std::vector<const BigMemoryObject *>();
65 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
66 * file. The first mesh in the file is loaded.
67 * \param [in] fileName - the name of MED file to read.
68 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
69 * mesh using decrRef() as it is no more needed.
70 * \throw If the file is not readable.
71 * \throw If there is no meshes in the file.
72 * \throw If the mesh in the file is of a not supported type.
74 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
76 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
79 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
80 throw INTERP_KERNEL::Exception(oss.str().c_str());
82 MEDFileUtilities::CheckFileForRead(fileName);
83 ParaMEDMEM::MEDCouplingMeshType meshType;
84 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
87 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
92 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
93 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
94 return (MEDFileUMesh *)ret.retn();
98 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
99 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
100 return (MEDFileCMesh *)ret.retn();
104 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
105 ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
106 return (MEDFileCurveLinearMesh *)ret.retn();
110 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
111 throw INTERP_KERNEL::Exception(oss.str().c_str());
117 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
118 * file. The mesh to load is specified by its name and numbers of a time step and an
120 * \param [in] fileName - the name of MED file to read.
121 * \param [in] mName - the name of the mesh to read.
122 * \param [in] dt - the number of a time step.
123 * \param [in] it - the number of an iteration.
124 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
125 * mesh using decrRef() as it is no more needed.
126 * \throw If the file is not readable.
127 * \throw If there is no mesh with given attributes in the file.
128 * \throw If the mesh in the file is of a not supported type.
130 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
132 MEDFileUtilities::CheckFileForRead(fileName);
133 ParaMEDMEM::MEDCouplingMeshType meshType;
134 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
137 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
142 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
143 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
144 return (MEDFileUMesh *)ret.retn();
148 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
149 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
150 return (MEDFileCMesh *)ret.retn();
154 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
155 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
156 return (MEDFileCurveLinearMesh *)ret.retn();
160 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
161 throw INTERP_KERNEL::Exception(oss.str().c_str());
167 * Writes \a this mesh into an open MED file specified by its descriptor.
168 * \param [in] fid - the MED file descriptor.
169 * \throw If the mesh name is not set.
170 * \throw If the file is open for reading only.
171 * \throw If the writing mode == 1 and the same data is present in an existing file.
173 void MEDFileMesh::write(med_idt fid) const
176 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
178 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
183 * Writes \a this mesh into a MED file specified by its name.
184 * \param [in] fileName - the MED file name.
185 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
186 * - 2 - erase; an existing file is removed.
187 * - 1 - append; same data should not be present in an existing file.
188 * - 0 - overwrite; same data present in an existing file is overwritten.
189 * \throw If the mesh name is not set.
190 * \throw If \a mode == 1 and the same data is present in an existing file.
192 void MEDFileMesh::write(const std::string& fileName, int mode) const
194 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
195 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
196 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
197 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
202 * Checks if \a this and another mesh are equal.
203 * \param [in] other - the mesh to compare with.
204 * \param [in] eps - a precision used to compare real values.
205 * \param [in,out] what - the string returning description of unequal data.
206 * \return bool - \c true if the meshes are equal, \c false, else.
208 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
210 if(_order!=other->_order)
212 what="Orders differ !";
215 if(_iteration!=other->_iteration)
217 what="Iterations differ !";
220 if(fabs(_time-other->_time)>eps)
222 what="Time values differ !";
225 if(_dt_unit!=other->_dt_unit)
227 what="Time units differ !";
230 if(_name!=other->_name)
232 what="Names differ !";
235 //univ_name has been ignored -> not a bug because it is a mutable attribute
236 if(_desc_name!=other->_desc_name)
238 what="Description names differ !";
241 if(!areGrpsEqual(other,what))
243 if(!areFamsEqual(other,what))
248 void MEDFileMesh::setName(const std::string& name)
254 * Clears redundant attributes of incorporated data arrays.
256 void MEDFileMesh::clearNonDiscrAttributes() const
261 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
263 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
265 if((*it).first==_name)
275 * Copies data on groups and families from another mesh.
276 * \param [in] other - the mesh to copy the data from.
278 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
280 _groups=other._groups;
281 _families=other._families;
286 * This method clear all the groups in the map.
287 * So this method does not operate at all on arrays.
288 * So this method can lead to orphan families.
290 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
292 void MEDFileMesh::clearGrpMap()
298 * This method clear all the families in the map.
299 * So this method does not operate at all on arrays.
300 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
302 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
304 void MEDFileMesh::clearFamMap()
310 * This method clear all the families and groups in the map.
311 * So this method does not operate at all on arrays.
312 * As all groups and families entry will be removed after
313 * 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.
315 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
317 void MEDFileMesh::clearFamGrpMaps()
324 * Returns names of families constituting a group.
325 * \param [in] name - the name of the group of interest.
326 * \return std::vector<std::string> - a sequence of names of the families.
327 * \throw If the name of a nonexistent group is specified.
329 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
331 std::string oname(name);
332 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
333 if(it==_groups.end())
335 std::vector<std::string> grps=getGroupsNames();
336 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
337 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
338 throw INTERP_KERNEL::Exception(oss.str().c_str());
344 * Returns names of families constituting some groups.
345 * \param [in] grps - a sequence of names of groups of interest.
346 * \return std::vector<std::string> - a sequence of names of the families.
347 * \throw If a name of a nonexistent group is present in \a grps.
349 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
351 std::set<std::string> fams;
352 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
354 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
355 if(it2==_groups.end())
357 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
358 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
359 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
360 throw INTERP_KERNEL::Exception(oss.str().c_str());
362 fams.insert((*it2).second.begin(),(*it2).second.end());
364 std::vector<std::string> fams2(fams.begin(),fams.end());
369 * Returns ids of families constituting a group.
370 * \param [in] name - the name of the group of interest.
371 * \return std::vector<int> - sequence of ids of the families.
372 * \throw If the name of a nonexistent group is specified.
374 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
376 std::string oname(name);
377 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
378 std::vector<std::string> grps=getGroupsNames();
379 if(it==_groups.end())
381 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
382 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
383 throw INTERP_KERNEL::Exception(oss.str().c_str());
385 return getFamiliesIds((*it).second);
389 * Sets names of families constituting a group. If data on families of this group is
390 * already present, it is overwritten. Every family in \a fams is checked, and if a
391 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
392 * \param [in] name - the name of the group of interest.
393 * \param [in] fams - a sequence of names of families constituting the group.
395 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
397 std::string oname(name);
399 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
401 std::map<std::string,int>::iterator it2=_families.find(*it1);
402 if(it2==_families.end())
408 * Sets families constituting a group. The families are specified by their ids.
409 * If a family name is not found by its id, an exception is thrown.
410 * If several families have same id, the first one in lexical order is taken.
411 * \param [in] name - the name of the group of interest.
412 * \param [in] famIds - a sequence of ids of families constituting the group.
413 * \throw If a family name is not found by its id.
415 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
417 std::string oname(name);
418 std::vector<std::string> fams(famIds.size());
420 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
422 std::string name2=getFamilyNameGivenId(*it1);
429 * Returns names of groups including a given family.
430 * \param [in] name - the name of the family of interest.
431 * \return std::vector<std::string> - a sequence of names of groups including the family.
433 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
435 std::vector<std::string> ret;
436 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
438 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
441 ret.push_back((*it1).first);
449 * Adds an existing family to groups.
450 * \param [in] famName - a name of family to add to \a grps.
451 * \param [in] grps - a sequence of group names to add the family in.
452 * \throw If a family named \a famName not yet exists.
454 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
456 std::string fName(famName);
457 const std::map<std::string,int>::const_iterator it=_families.find(fName);
458 if(it==_families.end())
460 std::vector<std::string> fams=getFamiliesNames();
461 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
462 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
463 throw INTERP_KERNEL::Exception(oss.str().c_str());
465 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
467 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
468 if(it2!=_groups.end())
469 (*it2).second.push_back(fName);
472 std::vector<std::string> grps2(1,fName);
479 * Returns names of all groups of \a this mesh.
480 * \return std::vector<std::string> - a sequence of group names.
482 std::vector<std::string> MEDFileMesh::getGroupsNames() const
484 std::vector<std::string> ret(_groups.size());
486 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
492 * Returns names of all families of \a this mesh.
493 * \return std::vector<std::string> - a sequence of family names.
495 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
497 std::vector<std::string> ret(_families.size());
499 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
505 * Changes a name of every family, included in one group only, to be same as the group name.
506 * \throw If there are families with equal names in \a this mesh.
508 void MEDFileMesh::assignFamilyNameWithGroupName()
510 std::map<std::string, std::vector<std::string> > groups(_groups);
511 std::map<std::string,int> newFams;
512 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
514 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
515 if(grps.size()==1 && groups[grps[0]].size()==1)
517 if(newFams.find(grps[0])!=newFams.end())
519 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
520 throw INTERP_KERNEL::Exception(oss.str().c_str());
522 newFams[grps[0]]=(*it).second;
523 std::vector<std::string>& grps2=groups[grps[0]];
524 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
529 if(newFams.find((*it).first)!=newFams.end())
531 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
532 throw INTERP_KERNEL::Exception(oss.str().c_str());
534 newFams[(*it).first]=(*it).second;
542 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
544 * \return the removed groups.
546 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
548 std::vector<std::string> ret;
549 std::map<std::string, std::vector<std::string> > newGrps;
550 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
552 if((*it).second.empty())
553 ret.push_back((*it).first);
555 newGrps[(*it).first]=(*it).second;
563 * Removes a group from \a this mesh.
564 * \param [in] name - the name of the group to remove.
565 * \throw If no group with such a \a name exists.
567 void MEDFileMesh::removeGroup(const std::string& name)
569 std::string oname(name);
570 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
571 std::vector<std::string> grps=getGroupsNames();
572 if(it==_groups.end())
574 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
575 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
576 throw INTERP_KERNEL::Exception(oss.str().c_str());
582 * Removes a family from \a this mesh.
583 * \param [in] name - the name of the family to remove.
584 * \throw If no family with such a \a name exists.
586 void MEDFileMesh::removeFamily(const std::string& name)
588 std::string oname(name);
589 std::map<std::string, int >::iterator it=_families.find(oname);
590 std::vector<std::string> fams=getFamiliesNames();
591 if(it==_families.end())
593 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
594 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
595 throw INTERP_KERNEL::Exception(oss.str().c_str());
598 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
600 std::vector<std::string>& v=(*it3).second;
601 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
608 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
609 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
610 * family field whatever its level. This method also suppresses the orphan families.
612 * \return - The list of removed groups names.
614 * \sa MEDFileMesh::removeOrphanFamilies.
616 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
618 removeOrphanFamilies();
619 return removeEmptyGroups();
623 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
624 * 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.
626 * \return - The list of removed families names.
627 * \sa MEDFileMesh::removeOrphanGroups.
629 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
632 std::vector<std::string> ret;
633 if(!((DataArrayInt*)allFamIdsInUse))
635 ret=getFamiliesNames();
636 _families.clear(); _groups.clear();
639 std::map<std::string,int> famMap;
640 std::map<std::string, std::vector<std::string> > grps(_groups);
641 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
643 if(allFamIdsInUse->presenceOfValue((*it).second))
644 famMap[(*it).first]=(*it).second;
647 ret.push_back((*it).first);
648 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
649 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
651 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
652 std::vector<std::string>& famv=(*it3).second;
653 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
659 { _families=famMap; _groups=grps; }
664 * Renames a group in \a this mesh.
665 * \param [in] oldName - a current name of the group to rename.
666 * \param [in] newName - a new group name.
667 * \throw If no group named \a oldName exists in \a this mesh.
668 * \throw If a group named \a newName already exists.
670 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
672 std::string oname(oldName);
673 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
674 std::vector<std::string> grps=getGroupsNames();
675 if(it==_groups.end())
677 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
678 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
679 throw INTERP_KERNEL::Exception(oss.str().c_str());
681 std::string nname(newName);
682 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
683 if(it2!=_groups.end())
685 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
686 throw INTERP_KERNEL::Exception(oss.str().c_str());
688 std::vector<std::string> cpy=(*it).second;
690 _groups[newName]=cpy;
694 * Changes an id of a family in \a this mesh.
695 * This method calls changeFamilyIdArr().
696 * \param [in] oldId - a current id of the family.
697 * \param [in] newId - a new family id.
699 void MEDFileMesh::changeFamilyId(int oldId, int newId)
701 changeFamilyIdArr(oldId,newId);
702 std::map<std::string,int> fam2;
703 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
705 if((*it).second==oldId)
706 fam2[(*it).first]=newId;
708 fam2[(*it).first]=(*it).second;
714 * Renames a family in \a this mesh.
715 * \param [in] oldName - a current name of the family to rename.
716 * \param [in] newName - a new family name.
717 * \throw If no family named \a oldName exists in \a this mesh.
718 * \throw If a family named \a newName already exists.
720 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
722 std::string oname(oldName);
723 std::map<std::string, int >::iterator it=_families.find(oname);
724 std::vector<std::string> fams=getFamiliesNames();
725 if(it==_families.end())
727 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
728 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
729 throw INTERP_KERNEL::Exception(oss.str().c_str());
731 std::string nname(newName);
732 std::map<std::string, int >::iterator it2=_families.find(nname);
733 if(it2!=_families.end())
735 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
736 throw INTERP_KERNEL::Exception(oss.str().c_str());
738 int cpy=(*it).second;
740 _families[newName]=cpy;
741 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
743 std::vector<std::string>& v=(*it3).second;
744 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
751 * Checks if \a this and another mesh contains the same families.
752 * \param [in] other - the mesh to compare with \a this one.
753 * \param [in,out] what - an unused parameter.
754 * \return bool - \c true if number of families and their ids are the same in the two
755 * meshes. Families with the id == \c 0 are not considered.
757 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
759 if(_families==other->_families)
761 std::map<std::string,int> fam0;
762 std::map<std::string,int> fam1;
763 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
765 fam0[(*it).first]=(*it).second;
766 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
768 fam1[(*it).first]=(*it).second;
773 * Checks if \a this and another mesh contains the same groups.
774 * \param [in] other - the mesh to compare with \a this one.
775 * \param [in,out] what - a string describing a difference of groups of the two meshes
776 * in case if this method returns \c false.
777 * \return bool - \c true if number of groups and families constituting them are the
778 * same in the two meshes.
780 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
782 if(_groups==other->_groups)
785 std::size_t sz=_groups.size();
786 if(sz!=other->_groups.size())
788 what="Groups differ because not same number !\n";
793 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
794 for(std::size_t i=0;i<sz && ret;i++,it1++)
796 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
797 if(it2!=other->_groups.end())
799 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
800 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
806 what="A group in first mesh exists not in other !\n";
812 std::ostringstream oss; oss << "Groups description differs :\n";
813 oss << "First group description :\n";
814 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
816 oss << " Group \"" << (*it).first << "\" on following families :\n";
817 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
818 oss << " \"" << *it2 << "\n";
820 oss << "Second group description :\n";
821 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
823 oss << " Group \"" << (*it).first << "\" on following families :\n";
824 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
825 oss << " \"" << *it2 << "\n";
833 * Checks if a group with a given name exists in \a this mesh.
834 * \param [in] groupName - the group name.
835 * \return bool - \c true the group \a groupName exists in \a this mesh.
837 bool MEDFileMesh::existsGroup(const std::string& groupName) const
839 std::string grpName(groupName);
840 return _groups.find(grpName)!=_groups.end();
844 * Checks if a family with a given id exists in \a this mesh.
845 * \param [in] famId - the family id.
846 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
848 bool MEDFileMesh::existsFamily(int famId) const
850 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
851 if((*it2).second==famId)
857 * Checks if a family with a given name exists in \a this mesh.
858 * \param [in] familyName - the family name.
859 * \return bool - \c true the family \a familyName exists in \a this mesh.
861 bool MEDFileMesh::existsFamily(const std::string& familyName) const
863 std::string fname(familyName);
864 return _families.find(fname)!=_families.end();
868 * Sets an id of a family.
869 * \param [in] familyName - the family name.
870 * \param [in] id - a new id of the family.
872 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
874 std::string fname(familyName);
878 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
880 std::string fname(familyName);
881 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
884 if((*it).first!=familyName)
886 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
887 throw INTERP_KERNEL::Exception(oss.str().c_str());
894 * Adds a family to \a this mesh.
895 * \param [in] familyName - a name of the family.
896 * \param [in] famId - an id of the family.
897 * \throw If a family with the same name or id already exists in \a this mesh.
899 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
901 std::string fname(familyName);
902 std::map<std::string,int>::const_iterator it=_families.find(fname);
903 if(it==_families.end())
905 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
906 if((*it2).second==famId)
908 std::ostringstream oss;
909 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
910 throw INTERP_KERNEL::Exception(oss.str().c_str());
912 _families[fname]=famId;
916 if((*it).second!=famId)
918 std::ostringstream oss;
919 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
920 throw INTERP_KERNEL::Exception(oss.str().c_str());
926 * Creates a group including all mesh entities of given dimension.
927 * \warning This method does \b not guarantee that the created group includes mesh
928 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
929 * present in family fields of different dimensions. To assure this, call
930 * ensureDifferentFamIdsPerLevel() \b before calling this method.
931 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
933 * \param [in] groupName - a name of the new group.
934 * \throw If a group named \a groupName already exists.
935 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
936 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
938 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
940 std::string grpName(groupName);
941 std::vector<int> levs=getNonEmptyLevelsExt();
942 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
944 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
945 oss << "Available relative ext levels are : ";
946 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
947 throw INTERP_KERNEL::Exception(oss.str().c_str());
949 if(existsGroup(groupName))
951 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
952 oss << "Already existing groups are : ";
953 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
954 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
955 throw INTERP_KERNEL::Exception(oss.str().c_str());
957 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
959 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
960 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
961 std::vector<std::string> familiesOnWholeGroup;
962 for(const int *it=famIds->begin();it!=famIds->end();it++)
965 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
967 _groups[grpName]=familiesOnWholeGroup;
971 * Ensures that given family ids do not present in family fields of dimensions different
972 * than given ones. If a family id is present in the family fields of dimensions different
973 * than the given ones, a new family is created and the whole data is updated accordingly.
974 * \param [in] famIds - a sequence of family ids to check.
975 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
976 * famIds should exclusively belong.
977 * \return bool - \c true if no modification is done in \a this mesh by this method.
979 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
981 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
982 std::vector<int> levs=getNonEmptyLevelsExt();
983 std::set<int> levs2(levs.begin(),levs.end());
984 std::vector<int> levsToTest;
985 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
986 std::set<int> famIds2(famIds.begin(),famIds.end());
989 if(!_families.empty())
990 maxFamId=getMaxFamilyId()+1;
991 std::vector<std::string> allFams=getFamiliesNames();
992 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
994 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
997 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
998 std::vector<int> tmp;
999 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1000 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1003 std::string famName=getFamilyNameGivenId(*it2);
1004 std::ostringstream oss; oss << "Family_" << maxFamId;
1005 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1006 addFamilyOnAllGroupsHaving(famName,zeName);
1007 _families[zeName]=maxFamId;
1008 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1017 * Adds a family to a given group in \a this mesh. If the group with a given name does
1018 * not exist, it is created.
1019 * \param [in] grpName - the name of the group to add the family in.
1020 * \param [in] famName - the name of the family to add to the group named \a grpName.
1021 * \throw If \a grpName or \a famName is an empty string.
1022 * \throw If no family named \a famName is present in \a this mesh.
1024 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1026 std::string grpn(grpName);
1027 std::string famn(famName);
1028 if(grpn.empty() || famn.empty())
1029 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1030 std::vector<std::string> fams=getFamiliesNames();
1031 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1033 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1034 oss << "Create this family or choose an existing one ! Existing fams are : ";
1035 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1036 throw INTERP_KERNEL::Exception(oss.str().c_str());
1038 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1039 if(it==_groups.end())
1041 _groups[grpn].push_back(famn);
1045 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1046 if(it2==(*it).second.end())
1047 (*it).second.push_back(famn);
1052 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1053 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1054 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1056 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1058 std::string famNameCpp(famName);
1059 std::string otherCpp(otherFamName);
1060 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1062 std::vector<std::string>& v=(*it).second;
1063 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1065 v.push_back(otherCpp);
1070 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1072 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1075 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1077 std::string fam(familyNameToChange);
1078 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1080 std::vector<std::string>& fams((*it).second);
1081 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1085 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1091 * Returns a name of the family having a given id or, if no such a family exists, creates
1092 * a new uniquely named family and returns its name.
1093 * \param [in] id - the id of the family whose name is required.
1094 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1095 * \return std::string - the name of the existing or the created family.
1096 * \throw If it is not possible to create a unique family name.
1098 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1100 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1104 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1105 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1106 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1107 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1109 * This method will throws an exception if it is not possible to create a unique family name.
1111 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1113 std::vector<std::string> famAlreadyExisting(families.size());
1115 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1117 if((*it).second!=id)
1119 famAlreadyExisting[ii]=(*it).first;
1128 std::ostringstream oss; oss << "Family_" << id;
1129 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1135 * Sets names and ids of all families in \a this mesh.
1136 * \param [in] info - a map of a family name to a family id.
1138 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1144 * Sets names of all groups and families constituting them in \a this mesh.
1145 * \param [in] info - a map of a group name to a vector of names of families
1146 * constituting the group.
1148 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1154 * Returns an id of the family having a given name.
1155 * \param [in] name - the name of the family of interest.
1156 * \return int - the id of the family of interest.
1157 * \throw If no family with such a \a name exists.
1159 int MEDFileMesh::getFamilyId(const std::string& name) const
1161 std::string oname(name);
1162 std::map<std::string, int>::const_iterator it=_families.find(oname);
1163 std::vector<std::string> fams=getFamiliesNames();
1164 if(it==_families.end())
1166 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1167 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1168 throw INTERP_KERNEL::Exception(oss.str().c_str());
1170 return (*it).second;
1174 * Returns ids of the families having given names.
1175 * \param [in] fams - a sequence of the names of families of interest.
1176 * \return std::vector<int> - a sequence of the ids of families of interest.
1177 * \throw If \a fams contains a name of an inexistent family.
1179 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1181 std::vector<int> ret(fams.size());
1183 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1185 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1186 if(it2==_families.end())
1188 std::vector<std::string> fams2=getFamiliesNames();
1189 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1190 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1191 throw INTERP_KERNEL::Exception(oss.str().c_str());
1193 ret[i]=(*it2).second;
1199 * Returns a maximal abs(id) of families in \a this mesh.
1200 * \return int - the maximal norm of family id.
1201 * \throw If there are no families in \a this mesh.
1203 int MEDFileMesh::getMaxAbsFamilyId() const
1205 if(_families.empty())
1206 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1207 int ret=-std::numeric_limits<int>::max();
1208 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1210 ret=std::max(std::abs((*it).second),ret);
1216 * Returns a maximal id of families in \a this mesh.
1217 * \return int - the maximal family id.
1218 * \throw If there are no families in \a this mesh.
1220 int MEDFileMesh::getMaxFamilyId() const
1222 if(_families.empty())
1223 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1224 int ret=-std::numeric_limits<int>::max();
1225 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1227 ret=std::max((*it).second,ret);
1233 * Returns a minimal id of families in \a this mesh.
1234 * \return int - the minimal family id.
1235 * \throw If there are no families in \a this mesh.
1237 int MEDFileMesh::getMinFamilyId() const
1239 if(_families.empty())
1240 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1241 int ret=std::numeric_limits<int>::max();
1242 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1244 ret=std::min((*it).second,ret);
1250 * Returns a maximal id of families in \a this mesh. Not only named families are
1251 * considered but all family fields as well.
1252 * \return int - the maximal family id.
1254 int MEDFileMesh::getTheMaxAbsFamilyId() const
1256 int m1=-std::numeric_limits<int>::max();
1257 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1258 m1=std::max(std::abs((*it).second),m1);
1259 int m2=getMaxAbsFamilyIdInArrays();
1260 return std::max(m1,m2);
1264 * Returns a maximal id of families in \a this mesh. Not only named families are
1265 * considered but all family fields as well.
1266 * \return int - the maximal family id.
1268 int MEDFileMesh::getTheMaxFamilyId() const
1270 int m1=-std::numeric_limits<int>::max();
1271 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1272 m1=std::max((*it).second,m1);
1273 int m2=getMaxFamilyIdInArrays();
1274 return std::max(m1,m2);
1278 * Returns a minimal id of families in \a this mesh. Not only named families are
1279 * considered but all family fields as well.
1280 * \return int - the minimal family id.
1282 int MEDFileMesh::getTheMinFamilyId() const
1284 int m1=std::numeric_limits<int>::max();
1285 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1286 m1=std::min((*it).second,m1);
1287 int m2=getMinFamilyIdInArrays();
1288 return std::min(m1,m2);
1292 * This method only considers the maps. The contain of family array is ignored here.
1294 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1296 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1298 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1300 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1301 v.insert((*it).second);
1302 ret->alloc((int)v.size(),1);
1303 std::copy(v.begin(),v.end(),ret->getPointer());
1308 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1310 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1312 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1314 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1315 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1316 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1318 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1319 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1320 if((DataArrayInt *) ret)
1321 ret=dv->buildUnion(ret);
1329 * true is returned if no modification has been needed. false if family
1330 * renumbering has been needed.
1332 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1334 std::vector<int> levs=getNonEmptyLevelsExt();
1335 std::set<int> allFamIds;
1336 int maxId=getMaxFamilyId()+1;
1337 std::map<int,std::vector<int> > famIdsToRenum;
1338 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1340 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1343 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1345 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1347 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1349 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1352 if(famIdsToRenum.empty())
1354 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1355 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1357 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1358 int *famIdsToChange=fam->getPointer();
1359 std::map<int,int> ren;
1360 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1362 if(allIds->presenceOfValue(*it3))
1364 std::string famName=getFamilyNameGivenId(*it3);
1365 std::vector<std::string> grps=getGroupsOnFamily(famName);
1368 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1369 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1370 addFamilyOnGrp((*it4),newFam);
1373 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1374 for(const int *id=ids->begin();id!=ids->end();id++)
1375 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1381 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1382 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1383 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1384 * This method will throw an exception if a same family id is detected in different level.
1385 * \warning This policy is the opposite of those in MED file documentation ...
1387 void MEDFileMesh::normalizeFamIdsTrio()
1389 ensureDifferentFamIdsPerLevel();
1390 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1391 std::vector<int> levs=getNonEmptyLevelsExt();
1392 std::set<int> levsS(levs.begin(),levs.end());
1393 std::set<std::string> famsFetched;
1394 std::map<std::string,int> families;
1395 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1398 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1402 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1403 std::map<int,int> ren;
1404 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1406 int nbOfTuples=fam->getNumberOfTuples();
1407 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1408 for(int *w=start;w!=start+nbOfTuples;w++)
1410 for(const int *it=tmp->begin();it!=tmp->end();it++)
1412 if(allIds->presenceOfValue(*it))
1414 std::string famName=getFamilyNameGivenId(*it);
1415 families[famName]=ren[*it];
1416 famsFetched.insert(famName);
1421 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1424 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1428 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1429 std::map<int,int> ren;
1430 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1432 int nbOfTuples=fam->getNumberOfTuples();
1433 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1434 for(int *w=start;w!=start+nbOfTuples;w++)
1436 for(const int *it=tmp->begin();it!=tmp->end();it++)
1438 if(allIds->presenceOfValue(*it))
1440 std::string famName=getFamilyNameGivenId(*it);
1441 families[famName]=ren[*it];
1442 famsFetched.insert(famName);
1447 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1449 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1452 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1453 fam->fillWithZero();
1454 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1455 if(allIds->presenceOfValue(*it3))
1457 std::string famName=getFamilyNameGivenId(*it3);
1458 families[famName]=0;
1459 famsFetched.insert(famName);
1464 std::vector<std::string> allFams=getFamiliesNames();
1465 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1466 std::set<std::string> unFetchedIds;
1467 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1468 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1469 families[*it4]=_families[*it4];
1474 * This method normalizes fam id with the following policy.
1475 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1476 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1477 * This method will throw an exception if a same family id is detected in different level.
1479 void MEDFileMesh::normalizeFamIdsMEDFile()
1481 ensureDifferentFamIdsPerLevel();
1482 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1483 std::vector<int> levs=getNonEmptyLevelsExt();
1484 std::set<int> levsS(levs.begin(),levs.end());
1485 std::set<std::string> famsFetched;
1486 std::map<std::string,int> families;
1488 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1491 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1494 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1495 std::map<int,int> ren;
1496 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1498 int nbOfTuples=fam->getNumberOfTuples();
1499 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1500 for(int *w=start;w!=start+nbOfTuples;w++)
1502 for(const int *it=tmp->begin();it!=tmp->end();it++)
1504 if(allIds->presenceOfValue(*it))
1506 std::string famName=getFamilyNameGivenId(*it);
1507 families[famName]=ren[*it];
1508 famsFetched.insert(famName);
1514 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1516 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1519 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1520 std::map<int,int> ren;
1521 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1523 int nbOfTuples=fam->getNumberOfTuples();
1524 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1525 for(int *w=start;w!=start+nbOfTuples;w++)
1527 for(const int *it=tmp->begin();it!=tmp->end();it++)
1529 if(allIds->presenceOfValue(*it))
1531 std::string famName=getFamilyNameGivenId(*it);
1532 families[famName]=ren[*it];
1533 famsFetched.insert(famName);
1539 std::vector<std::string> allFams=getFamiliesNames();
1540 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1541 std::set<std::string> unFetchedIds;
1542 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1543 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1544 families[*it4]=_families[*it4];
1549 * Returns a name of the family by its id. If there are several families having the given
1550 * id, the name first in lexical order is returned.
1551 * \param [in] id - the id of the family whose name is required.
1552 * \return std::string - the name of the found family.
1553 * \throw If no family with the given \a id exists.
1555 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1557 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1558 if((*it).second==id)
1560 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1561 throw INTERP_KERNEL::Exception(oss.str().c_str());
1565 * Returns a string describing \a this mesh. This description includes the mesh name and
1566 * the mesh description string.
1567 * \return std::string - the mesh information string.
1569 std::string MEDFileMesh::simpleRepr() const
1571 std::ostringstream oss;
1572 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1573 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1574 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1579 * Returns ids of mesh entities contained in a given group of a given dimension.
1580 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1582 * \param [in] grp - the name of the group of interest.
1583 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1584 * returned instead of ids.
1585 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1586 * numbers, if available and required, of mesh entities of the group. The caller
1587 * is to delete this array using decrRef() as it is no more needed.
1588 * \throw If the name of a nonexistent group is specified.
1589 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1591 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1593 std::vector<std::string> tmp(1);
1595 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1601 * Returns ids of mesh entities contained in given groups of a given dimension.
1602 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1604 * \param [in] grps - the names of the groups of interest.
1605 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1606 * returned instead of ids.
1607 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1608 * numbers, if available and required, of mesh entities of the groups. The caller
1609 * is to delete this array using decrRef() as it is no more needed.
1610 * \throw If the name of a nonexistent group is present in \a grps.
1611 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1613 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1615 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1616 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1620 * Returns ids of mesh entities contained in a given family of a given dimension.
1621 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1623 * \param [in] fam - the name of the family of interest.
1624 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1625 * returned instead of ids.
1626 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1627 * numbers, if available and required, of mesh entities of the family. The caller
1628 * is to delete this array using decrRef() as it is no more needed.
1629 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1631 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1633 std::vector<std::string> tmp(1);
1635 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1641 * Returns ids of nodes contained in a given group.
1642 * \param [in] grp - the name of the group of interest.
1643 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1644 * returned instead of ids.
1645 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1646 * numbers, if available and required, of nodes of the group. The caller
1647 * is to delete this array using decrRef() as it is no more needed.
1648 * \throw If the name of a nonexistent group is specified.
1649 * \throw If the family field is missing for nodes.
1651 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1653 std::vector<std::string> tmp(1);
1655 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1661 * Returns ids of nodes contained in given groups.
1662 * \param [in] grps - the names of the groups of interest.
1663 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1664 * returned instead of ids.
1665 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1666 * numbers, if available and required, of nodes of the groups. The caller
1667 * is to delete this array using decrRef() as it is no more needed.
1668 * \throw If the name of a nonexistent group is present in \a grps.
1669 * \throw If the family field is missing for nodes.
1671 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1673 return getGroupsArr(1,grps,renum);
1677 * Returns ids of nodes contained in a given group.
1678 * \param [in] grp - the name of the group of interest.
1679 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1680 * returned instead of ids.
1681 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1682 * numbers, if available and required, of nodes of the group. The caller
1683 * is to delete this array using decrRef() as it is no more needed.
1684 * \throw If the name of a nonexistent group is specified.
1685 * \throw If the family field is missing for nodes.
1687 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1689 std::vector<std::string> tmp(1);
1691 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1697 * Returns ids of nodes contained in given families.
1698 * \param [in] fams - the names of the families of interest.
1699 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1700 * returned instead of ids.
1701 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1702 * numbers, if available and required, of nodes of the families. The caller
1703 * is to delete this array using decrRef() as it is no more needed.
1704 * \throw If the family field is missing for nodes.
1706 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1708 return getFamiliesArr(1,fams,renum);
1712 * Adds groups of given dimension and creates corresponding families and family fields
1713 * given ids of mesh entities of each group.
1714 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1715 * \param [in] grps - a sequence of arrays of ids each describing a group.
1716 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1718 * \throw If names of some groups in \a grps are equal.
1719 * \throw If \a grps includes a group with an empty name.
1720 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1721 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1723 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1727 std::set<std::string> grpsName;
1728 std::vector<std::string> grpsName2(grps.size());
1731 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1733 grpsName.insert((*it)->getName());
1734 grpsName2[i]=(*it)->getName();
1736 if(grpsName.size()!=grps.size())
1737 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1738 if(grpsName.find(std::string(""))!=grpsName.end())
1739 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1740 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1741 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1742 std::vector< std::vector<int> > fidsOfGroups;
1745 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1749 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1750 for(unsigned int ii=0;ii<grps.size();ii++)
1752 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1753 grps2[ii]->setName(grps[ii]->getName());
1755 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1756 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1759 if(!_families.empty())
1760 offset=getMaxAbsFamilyId()+1;
1761 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1762 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1763 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1764 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1768 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1769 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1770 * For the moment, the two last input parameters are not taken into account.
1772 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1774 std::map<int,std::string> famInv;
1775 for(const int *it=famIds->begin();it!=famIds->end();it++)
1777 std::ostringstream oss;
1778 oss << "Family_" << (*it);
1779 _families[oss.str()]=(*it);
1780 famInv[*it]=oss.str();
1783 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1785 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1787 _groups[grpNames[i]].push_back(famInv[*it2]);
1792 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1794 std::vector<int> levs(getNonEmptyLevels());
1795 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1796 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1798 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1799 ret.insert(ret.end(),elts.begin(),elts.end());
1804 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1806 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1807 return mLev->getDistributionOfTypes();
1810 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1812 famArr->applyLin(offset>0?1:-1,offset,0);
1813 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1816 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1817 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1822 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1823 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1824 * If this method fails to find such a name it will throw an exception.
1826 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1829 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1832 std::size_t len=nameTry.length();
1833 for(std::size_t ii=1;ii<len;ii++)
1835 std::string tmp=nameTry.substr(ii,len-ii);
1836 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1842 for(std::size_t i=1;i<30;i++)
1844 std::string tmp1(nameTry.at(0),i);
1846 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1852 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1854 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1856 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1859 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
1861 std::size_t nbOfChunks=code.size()/3;
1862 if(code.size()%3!=0)
1863 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1865 for(std::size_t i=0;i<nbOfChunks;i++)
1874 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1875 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1876 * If _name is not empty and that 'm' has the same name nothing is done.
1877 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1879 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
1882 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1887 std::string name(m->getName());
1892 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1893 oss << name << "' ! Names must match !";
1894 throw INTERP_KERNEL::Exception(oss.str().c_str());
1898 if(_desc_name.empty())
1899 _desc_name=m->getDescription();
1902 std::string name(m->getDescription());
1905 if(_desc_name!=name)
1907 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1908 oss << name << "' ! Names must match !";
1909 throw INTERP_KERNEL::Exception(oss.str().c_str());
1915 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1917 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1918 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1920 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1921 oss << " - Groups lying on this family : ";
1922 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
1923 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1924 oss << std::endl << std::endl;
1929 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1930 * file. The mesh to load is specified by its name and numbers of a time step and an
1932 * \param [in] fileName - the name of MED file to read.
1933 * \param [in] mName - the name of the mesh to read.
1934 * \param [in] dt - the number of a time step.
1935 * \param [in] it - the number of an iteration.
1936 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1937 * mesh using decrRef() as it is no more needed.
1938 * \throw If the file is not readable.
1939 * \throw If there is no mesh with given attributes in the file.
1940 * \throw If the mesh in the file is not an unstructured one.
1942 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
1944 MEDFileUtilities::CheckFileForRead(fileName);
1945 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1946 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1950 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1951 * file. The first mesh in the file is loaded.
1952 * \param [in] fileName - the name of MED file to read.
1953 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1954 * mesh using decrRef() as it is no more needed.
1955 * \throw If the file is not readable.
1956 * \throw If there is no meshes in the file.
1957 * \throw If the mesh in the file is not an unstructured one.
1959 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
1961 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1964 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1965 throw INTERP_KERNEL::Exception(oss.str().c_str());
1967 MEDFileUtilities::CheckFileForRead(fileName);
1968 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1970 ParaMEDMEM::MEDCouplingMeshType meshType;
1972 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
1973 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
1977 * Returns an empty instance of MEDFileUMesh.
1978 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1979 * mesh using decrRef() as it is no more needed.
1981 MEDFileUMesh *MEDFileUMesh::New()
1983 return new MEDFileUMesh;
1986 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
1988 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
1989 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1993 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildren() const
1995 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
1996 if((const DataArrayDouble*)_coords)
1997 ret.push_back((const DataArrayDouble*)_coords);
1998 if((const DataArrayInt *)_fam_coords)
1999 ret.push_back((const DataArrayInt *)_fam_coords);
2000 if((const DataArrayInt *)_num_coords)
2001 ret.push_back((const DataArrayInt *)_num_coords);
2002 if((const DataArrayInt *)_rev_num_coords)
2003 ret.push_back((const DataArrayInt *)_rev_num_coords);
2004 if((const DataArrayAsciiChar *)_name_coords)
2005 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2006 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2007 if((const MEDFileUMeshSplitL1*) *it)
2008 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2012 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2014 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2018 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2020 return new MEDFileUMesh;
2023 MEDFileMesh *MEDFileUMesh::deepCpy() const
2025 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2026 if((const DataArrayDouble*)_coords)
2027 ret->_coords=_coords->deepCpy();
2028 if((const DataArrayInt*)_fam_coords)
2029 ret->_fam_coords=_fam_coords->deepCpy();
2030 if((const DataArrayInt*)_num_coords)
2031 ret->_num_coords=_num_coords->deepCpy();
2032 if((const DataArrayInt*)_rev_num_coords)
2033 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2034 if((const DataArrayAsciiChar*)_name_coords)
2035 ret->_name_coords=_name_coords->deepCpy();
2037 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2039 if((const MEDFileUMeshSplitL1 *)(*it))
2040 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2046 * Checks if \a this and another mesh are equal.
2047 * \param [in] other - the mesh to compare with.
2048 * \param [in] eps - a precision used to compare real values.
2049 * \param [in,out] what - the string returning description of unequal data.
2050 * \return bool - \c true if the meshes are equal, \c false, else.
2052 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2054 if(!MEDFileMesh::isEqual(other,eps,what))
2056 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2059 what="Mesh types differ ! This is unstructured and other is NOT !";
2062 clearNonDiscrAttributes();
2063 otherC->clearNonDiscrAttributes();
2064 const DataArrayDouble *coo1=_coords;
2065 const DataArrayDouble *coo2=otherC->_coords;
2066 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2068 what="Mismatch of coordinates ! One is defined and not other !";
2073 bool ret=coo1->isEqual(*coo2,eps);
2076 what="Coords differ !";
2080 const DataArrayInt *famc1=_fam_coords;
2081 const DataArrayInt *famc2=otherC->_fam_coords;
2082 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2084 what="Mismatch of families arr on nodes ! One is defined and not other !";
2089 bool ret=famc1->isEqual(*famc2);
2092 what="Families arr on node differ !";
2096 const DataArrayInt *numc1=_num_coords;
2097 const DataArrayInt *numc2=otherC->_num_coords;
2098 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2100 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2105 bool ret=numc1->isEqual(*numc2);
2108 what="Numbering arr on node differ !";
2112 const DataArrayAsciiChar *namec1=_name_coords;
2113 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2114 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2116 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2121 bool ret=namec1->isEqual(*namec2);
2124 what="Names arr on node differ !";
2128 if(_ms.size()!=otherC->_ms.size())
2130 what="Number of levels differs !";
2133 std::size_t sz=_ms.size();
2134 for(std::size_t i=0;i<sz;i++)
2136 const MEDFileUMeshSplitL1 *s1=_ms[i];
2137 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2138 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2140 what="Mismatch of presence of sub levels !";
2145 bool ret=s1->isEqual(s2,eps,what);
2154 * Clears redundant attributes of incorporated data arrays.
2156 void MEDFileUMesh::clearNonDiscrAttributes() const
2158 MEDFileMesh::clearNonDiscrAttributes();
2159 const DataArrayDouble *coo1=_coords;
2161 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2162 const DataArrayInt *famc1=_fam_coords;
2164 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2165 const DataArrayInt *numc1=_num_coords;
2167 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2168 const DataArrayAsciiChar *namc1=_name_coords;
2170 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2171 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2173 const MEDFileUMeshSplitL1 *tmp=(*it);
2175 tmp->clearNonDiscrAttributes();
2179 void MEDFileUMesh::setName(const std::string& name)
2181 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2182 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2183 (*it)->setName(name);
2184 MEDFileMesh::setName(name);
2187 MEDFileUMesh::MEDFileUMesh()
2191 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2194 loadUMeshFromFile(fid,mName,dt,it,mrs);
2196 catch(INTERP_KERNEL::Exception& e)
2201 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2203 MEDFileUMeshL2 loaderl2;
2204 ParaMEDMEM::MEDCouplingMeshType meshType;
2207 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2208 if(meshType!=UNSTRUCTURED)
2210 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2211 throw INTERP_KERNEL::Exception(oss.str().c_str());
2213 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2214 int lev=loaderl2.getNumberOfLevels();
2216 for(int i=0;i<lev;i++)
2218 if(!loaderl2.emptyLev(i))
2219 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2223 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2225 setName(loaderl2.getName());
2226 setDescription(loaderl2.getDescription());
2227 setUnivName(loaderl2.getUnivName());
2228 setIteration(loaderl2.getIteration());
2229 setOrder(loaderl2.getOrder());
2230 setTimeValue(loaderl2.getTime());
2231 setTimeUnit(loaderl2.getTimeUnit());
2232 _coords=loaderl2.getCoords();
2233 if(!mrs || mrs->isNodeFamilyFieldReading())
2234 _fam_coords=loaderl2.getCoordsFamily();
2235 if(!mrs || mrs->isNodeNumFieldReading())
2236 _num_coords=loaderl2.getCoordsNum();
2237 if(!mrs || mrs->isNodeNameFieldReading())
2238 _name_coords=loaderl2.getCoordsName();
2242 MEDFileUMesh::~MEDFileUMesh()
2246 void MEDFileUMesh::writeLL(med_idt fid) const
2248 const DataArrayDouble *coo=_coords;
2249 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2250 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2251 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2252 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2253 int spaceDim=coo?coo->getNumberOfComponents():0;
2254 int mdim=getMeshDimension();
2255 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2256 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2257 for(int i=0;i<spaceDim;i++)
2259 std::string info=coo->getInfoOnComponent(i);
2261 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2262 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
2263 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
2265 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2266 MEDmeshUniversalNameWr(fid,maa);
2267 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2268 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2269 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2270 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2271 (*it)->write(fid,meshName,mdim);
2272 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2276 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2277 * \return std::vector<int> - a sequence of the relative dimensions.
2279 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2281 std::vector<int> ret;
2283 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2284 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2291 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2292 * \return std::vector<int> - a sequence of the relative dimensions.
2294 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2296 std::vector<int> ret0=getNonEmptyLevels();
2297 if((const DataArrayDouble *) _coords)
2299 std::vector<int> ret(ret0.size()+1);
2301 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2307 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2309 std::vector<int> ret;
2310 const DataArrayInt *famCoo(_fam_coords);
2314 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2316 const MEDFileUMeshSplitL1 *cur(*it);
2318 if(cur->getFamilyField())
2324 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2326 std::vector<int> ret;
2327 const DataArrayInt *numCoo(_num_coords);
2331 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2333 const MEDFileUMeshSplitL1 *cur(*it);
2335 if(cur->getNumberField())
2341 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2343 std::vector<int> ret;
2344 const DataArrayAsciiChar *nameCoo(_name_coords);
2348 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2350 const MEDFileUMeshSplitL1 *cur(*it);
2352 if(cur->getNameField())
2359 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2360 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2361 * \param [in] grp - the name of the group of interest.
2362 * \return std::vector<int> - a sequence of the relative dimensions.
2364 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2366 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2367 return getFamsNonEmptyLevels(fams);
2371 * Returns all relative mesh levels (including nodes) where a given group is defined.
2372 * \param [in] grp - the name of the group of interest.
2373 * \return std::vector<int> - a sequence of the relative dimensions.
2375 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2377 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2378 return getFamsNonEmptyLevelsExt(fams);
2382 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2383 * To include nodes, call getFamNonEmptyLevelsExt() method.
2384 * \param [in] fam - the name of the family of interest.
2385 * \return std::vector<int> - a sequence of the relative dimensions.
2387 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2389 std::vector<std::string> fams(1,std::string(fam));
2390 return getFamsNonEmptyLevels(fams);
2394 * Returns all relative mesh levels (including nodes) where a given family is defined.
2395 * \param [in] fam - the name of the family of interest.
2396 * \return std::vector<int> - a sequence of the relative dimensions.
2398 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2400 std::vector<std::string> fams(1,std::string(fam));
2401 return getFamsNonEmptyLevelsExt(fams);
2405 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2406 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2407 * \param [in] grps - a sequence of names of the groups of interest.
2408 * \return std::vector<int> - a sequence of the relative dimensions.
2410 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2412 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2413 return getFamsNonEmptyLevels(fams);
2417 * Returns all relative mesh levels (including nodes) where given groups are defined.
2418 * \param [in] grps - a sequence of names of the groups of interest.
2419 * \return std::vector<int> - a sequence of the relative dimensions.
2421 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2423 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2424 return getFamsNonEmptyLevelsExt(fams);
2428 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2429 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2430 * \param [in] fams - the name of the family of interest.
2431 * \return std::vector<int> - a sequence of the relative dimensions.
2433 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2435 std::vector<int> ret;
2436 std::vector<int> levs=getNonEmptyLevels();
2437 std::vector<int> famIds=getFamiliesIds(fams);
2438 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2439 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2445 * Returns all relative mesh levels (including nodes) where given families are defined.
2446 * \param [in] fams - the names of the families of interest.
2447 * \return std::vector<int> - a sequence of the relative dimensions.
2449 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2451 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2452 const DataArrayInt *famCoords=_fam_coords;
2455 std::vector<int> famIds=getFamiliesIds(fams);
2456 if(famCoords->presenceOfValue(famIds))
2458 std::vector<int> ret(ret0.size()+1);
2460 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2468 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2469 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2470 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2473 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2475 std::vector<std::string> ret;
2476 std::vector<std::string> allGrps=getGroupsNames();
2477 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2479 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2480 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2486 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2488 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2489 if((const DataArrayInt *)_fam_coords)
2491 int val=_fam_coords->getMaxValue(tmp);
2492 ret=std::max(ret,std::abs(val));
2494 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2496 if((const MEDFileUMeshSplitL1 *)(*it))
2498 const DataArrayInt *da=(*it)->getFamilyField();
2501 int val=da->getMaxValue(tmp);
2502 ret=std::max(ret,std::abs(val));
2509 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2511 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2512 if((const DataArrayInt *)_fam_coords)
2514 int val=_fam_coords->getMaxValue(tmp);
2515 ret=std::max(ret,val);
2517 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2519 if((const MEDFileUMeshSplitL1 *)(*it))
2521 const DataArrayInt *da=(*it)->getFamilyField();
2524 int val=da->getMaxValue(tmp);
2525 ret=std::max(ret,val);
2532 int MEDFileUMesh::getMinFamilyIdInArrays() const
2534 int ret=std::numeric_limits<int>::max(),tmp=-1;
2535 if((const DataArrayInt *)_fam_coords)
2537 int val=_fam_coords->getMinValue(tmp);
2538 ret=std::min(ret,val);
2540 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2542 if((const MEDFileUMeshSplitL1 *)(*it))
2544 const DataArrayInt *da=(*it)->getFamilyField();
2547 int val=da->getMinValue(tmp);
2548 ret=std::min(ret,val);
2556 * Returns the dimension on cells in \a this mesh.
2557 * \return int - the mesh dimension.
2558 * \throw If there are no cells in this mesh.
2560 int MEDFileUMesh::getMeshDimension() const
2563 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2564 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2565 return (*it)->getMeshDimension()+lev;
2566 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2570 * Returns the space dimension of \a this mesh that is equal to number of components in
2571 * the node coordinates array.
2572 * \return int - the space dimension of \a this mesh.
2573 * \throw If the node coordinates array is not available.
2575 int MEDFileUMesh::getSpaceDimension() const
2577 const DataArrayDouble *coo=_coords;
2579 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2580 return coo->getNumberOfComponents();
2584 * Returns a string describing \a this mesh.
2585 * \return std::string - the mesh information string.
2587 std::string MEDFileUMesh::simpleRepr() const
2589 std::ostringstream oss;
2590 oss << MEDFileMesh::simpleRepr();
2591 const DataArrayDouble *coo=_coords;
2592 oss << "- The dimension of the space is ";
2593 static const char MSG1[]= "*** NO COORDS SET ***";
2594 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2596 oss << _coords->getNumberOfComponents() << std::endl;
2598 oss << MSG1 << std::endl;
2599 oss << "- Type of the mesh : UNSTRUCTURED\n";
2600 oss << "- Number of nodes : ";
2602 oss << _coords->getNumberOfTuples() << std::endl;
2604 oss << MSG1 << std::endl;
2605 std::size_t nbOfLev=_ms.size();
2606 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2607 for(std::size_t i=0;i<nbOfLev;i++)
2609 const MEDFileUMeshSplitL1 *lev=_ms[i];
2610 oss << " - Level #" << -((int) i) << " has dimension : ";
2613 oss << lev->getMeshDimension() << std::endl;
2614 lev->simpleRepr(oss);
2617 oss << MSG2 << std::endl;
2619 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2622 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2623 oss << "- Names of coordinates :" << std::endl;
2624 std::vector<std::string> vars=coo->getVarsOnComponent();
2625 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2626 oss << std::endl << "- Units of coordinates : " << std::endl;
2627 std::vector<std::string> units=coo->getUnitsOnComponent();
2628 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2630 oss << std::endl << std::endl;
2636 * Returns a full textual description of \a this mesh.
2637 * \return std::string - the string holding the mesh description.
2639 std::string MEDFileUMesh::advancedRepr() const
2641 return simpleRepr();
2645 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2646 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2647 * \return int - the number of entities.
2648 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2650 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2652 if(meshDimRelToMaxExt==1)
2654 if(!((const DataArrayDouble *)_coords))
2655 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2656 return _coords->getNumberOfTuples();
2658 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2662 * Returns the family field for mesh entities of a given dimension.
2663 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2664 * \return const DataArrayInt * - the family field. It is an array of ids of families
2665 * each mesh entity belongs to. It can be \c NULL.
2667 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2669 if(meshDimRelToMaxExt==1)
2671 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2672 return l1->getFamilyField();
2676 * Returns the optional numbers of mesh entities of a given dimension.
2677 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2678 * \return const DataArrayInt * - the array of the entity numbers.
2679 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2681 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2683 if(meshDimRelToMaxExt==1)
2685 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2686 return l1->getNumberField();
2689 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2691 if(meshDimRelToMaxExt==1)
2692 return _name_coords;
2693 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2694 return l1->getNameField();
2697 int MEDFileUMesh::getNumberOfNodes() const
2699 const DataArrayDouble *coo=_coords;
2701 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2702 return coo->getNumberOfTuples();
2705 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2707 std::size_t sz(st.getNumberOfItems());
2708 for(std::size_t i=0;i<sz;i++)
2710 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2711 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2712 if(st[i].getPflName().empty())
2713 m->computeNodeIdsAlg(nodesFetched);
2716 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2717 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2718 m2->computeNodeIdsAlg(nodesFetched);
2724 * Returns the optional numbers of mesh entities of a given dimension transformed using
2725 * DataArrayInt::invertArrayN2O2O2N().
2726 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2727 * \return const DataArrayInt * - the array of the entity numbers transformed using
2728 * DataArrayInt::invertArrayN2O2O2N().
2729 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2731 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2733 if(meshDimRelToMaxExt==1)
2735 if(!((const DataArrayInt *)_num_coords))
2736 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2737 return _rev_num_coords;
2739 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2740 return l1->getRevNumberField();
2744 * Returns a pointer to the node coordinates array of \a this mesh \b without
2745 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2747 DataArrayDouble *MEDFileUMesh::getCoords() const
2749 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2750 if((DataArrayDouble *)tmp)
2758 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2759 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2761 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2762 * \param [in] grp - the name of the group whose mesh entities are included in the
2764 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2765 * according to the optional numbers of entities, if available.
2766 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2767 * delete this mesh using decrRef() as it is no more needed.
2768 * \throw If the name of a nonexistent group is specified.
2769 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2771 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2773 synchronizeTinyInfoOnLeaves();
2774 std::vector<std::string> tmp(1);
2776 return getGroups(meshDimRelToMaxExt,tmp,renum);
2780 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2781 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2783 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2784 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2786 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2787 * according to the optional numbers of entities, if available.
2788 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2789 * delete this mesh using decrRef() as it is no more needed.
2790 * \throw If a name of a nonexistent group is present in \a grps.
2791 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2793 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2795 synchronizeTinyInfoOnLeaves();
2796 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2797 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2798 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2799 zeRet->setName(grps[0]);
2800 return zeRet.retn();
2804 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2805 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2807 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2808 * \param [in] fam - the name of the family whose mesh entities are included in the
2810 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2811 * according to the optional numbers of entities, if available.
2812 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2813 * delete this mesh using decrRef() as it is no more needed.
2814 * \throw If a name of a nonexistent family is present in \a grps.
2815 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2817 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2819 synchronizeTinyInfoOnLeaves();
2820 std::vector<std::string> tmp(1);
2822 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2826 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2827 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2829 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2830 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2832 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2833 * according to the optional numbers of entities, if available.
2834 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2835 * delete this mesh using decrRef() as it is no more needed.
2836 * \throw If a name of a nonexistent family is present in \a fams.
2837 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2839 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2841 synchronizeTinyInfoOnLeaves();
2842 if(meshDimRelToMaxExt==1)
2844 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2845 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2846 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2850 std::vector<int> famIds=getFamiliesIds(fams);
2851 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2852 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2854 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2856 zeRet=l1->getFamilyPart(0,0,renum);
2857 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2858 zeRet->setName(fams[0]);
2859 return zeRet.retn();
2863 * Returns ids of mesh entities contained in given families of a given dimension.
2864 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2866 * \param [in] fams - the names of the families of interest.
2867 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2868 * returned instead of ids.
2869 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2870 * numbers, if available and required, of mesh entities of the families. The caller
2871 * is to delete this array using decrRef() as it is no more needed.
2872 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2874 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2876 std::vector<int> famIds=getFamiliesIds(fams);
2877 if(meshDimRelToMaxExt==1)
2879 if((const DataArrayInt *)_fam_coords)
2881 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2883 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2885 da=_fam_coords->getIdsEqualList(0,0);
2887 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2892 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2894 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2896 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2898 return l1->getFamilyPartArr(0,0,renum);
2902 * Returns a MEDCouplingUMesh of a given relative dimension.
2903 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2904 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2905 * To build a valid MEDCouplingUMesh from the returned one in this case,
2906 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2907 * \param [in] meshDimRelToMax - the relative dimension of interest.
2908 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2909 * optional numbers of mesh entities.
2910 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2911 * delete using decrRef() as it is no more needed.
2912 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2913 * \sa getGenMeshAtLevel()
2915 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
2917 synchronizeTinyInfoOnLeaves();
2918 if(meshDimRelToMaxExt==1)
2922 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2923 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2924 umesh->setCoords(cc);
2925 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2926 umesh->setName(getName());
2930 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2931 return l1->getWholeMesh(renum);
2935 * Returns a MEDCouplingUMesh of a given relative dimension.
2936 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2937 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2938 * To build a valid MEDCouplingUMesh from the returned one in this case,
2939 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2940 * \param [in] meshDimRelToMax - the relative dimension of interest.
2941 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2942 * optional numbers of mesh entities.
2943 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2944 * delete using decrRef() as it is no more needed.
2945 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2946 * \sa getMeshAtLevel()
2948 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
2950 return getMeshAtLevel(meshDimRelToMax,renum);
2953 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
2955 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
2956 return l1->getDistributionOfTypes();
2960 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2961 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2962 * optional numbers of mesh entities.
2963 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2964 * delete using decrRef() as it is no more needed.
2965 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2967 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
2969 return getMeshAtLevel(0,renum);
2973 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2974 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2975 * optional numbers of mesh entities.
2976 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2977 * delete using decrRef() as it is no more needed.
2978 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2980 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
2982 return getMeshAtLevel(-1,renum);
2986 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2987 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2988 * optional numbers of mesh entities.
2989 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2990 * delete using decrRef() as it is no more needed.
2991 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2993 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
2995 return getMeshAtLevel(-2,renum);
2999 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3000 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3001 * optional numbers of mesh entities.
3002 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3003 * delete using decrRef() as it is no more needed.
3004 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3006 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3008 return getMeshAtLevel(-3,renum);
3012 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3013 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3014 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3015 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3017 void MEDFileUMesh::forceComputationOfParts() const
3019 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3021 const MEDFileUMeshSplitL1 *elt(*it);
3023 elt->forceComputationOfParts();
3028 * This method returns a vector of mesh parts containing each exactly one geometric type.
3029 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3030 * This method is only for memory aware users.
3031 * The returned pointers are **NOT** new object pointer. No need to mange them.
3033 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3035 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3036 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3040 * This method returns the part of \a this having the geometric type \a gt.
3041 * If such part is not existing an exception will be thrown.
3042 * The returned pointer is **NOT** new object pointer. No need to mange it.
3044 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3046 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3047 int lev=(int)cm.getDimension()-getMeshDimension();
3048 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3049 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3053 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3054 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3056 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3058 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3059 return sp->getGeoTypes();
3063 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3064 * \param [in] gt - the geometric type for which the family field is asked.
3065 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3066 * delete using decrRef() as it is no more needed.
3067 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3069 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3071 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3072 int lev=(int)cm.getDimension()-getMeshDimension();
3073 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3074 return sp->extractFamilyFieldOnGeoType(gt);
3078 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3079 * \param [in] gt - the geometric type for which the number field is asked.
3080 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3081 * delete using decrRef() as it is no more needed.
3082 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3084 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3086 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3087 int lev=(int)cm.getDimension()-getMeshDimension();
3088 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3089 return sp->extractNumberFieldOnGeoType(gt);
3092 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3094 if(meshDimRelToMaxExt==1)
3095 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3096 if(meshDimRelToMaxExt>1)
3097 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3098 int tracucedRk=-meshDimRelToMaxExt;
3099 if(tracucedRk>=(int)_ms.size())
3100 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3101 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3102 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3103 return _ms[tracucedRk];
3106 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3108 if(meshDimRelToMaxExt==1)
3109 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3110 if(meshDimRelToMaxExt>1)
3111 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3112 int tracucedRk=-meshDimRelToMaxExt;
3113 if(tracucedRk>=(int)_ms.size())
3114 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3115 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3116 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3117 return _ms[tracucedRk];
3120 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3122 if(-meshDimRelToMax>=(int)_ms.size())
3123 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3125 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3127 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3129 int ref=(*it)->getMeshDimension();
3130 if(ref+i!=meshDim-meshDimRelToMax)
3131 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3137 * Sets the node coordinates array of \a this mesh.
3138 * \param [in] coords - the new node coordinates array.
3139 * \throw If \a coords == \c NULL.
3141 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3144 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3145 coords->checkAllocated();
3146 int nbOfTuples=coords->getNumberOfTuples();
3149 _fam_coords=DataArrayInt::New();
3150 _fam_coords->alloc(nbOfTuples,1);
3151 _fam_coords->fillWithZero();
3152 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3153 if((MEDFileUMeshSplitL1 *)(*it))
3154 (*it)->setCoords(coords);
3158 * Removes all groups of a given dimension in \a this mesh.
3159 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3160 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3162 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3164 if(meshDimRelToMaxExt==1)
3166 if((DataArrayInt *)_fam_coords)
3167 _fam_coords->fillWithZero();
3170 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3171 l1->eraseFamilyField();
3176 * Removes all families with ids not present in the family fields of \a this mesh.
3178 void MEDFileUMesh::optimizeFamilies()
3180 std::vector<int> levs=getNonEmptyLevelsExt();
3181 std::set<int> allFamsIds;
3182 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3184 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3185 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3187 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3190 std::set<std::string> famNamesToKill;
3191 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3193 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3194 famNamesToKill.insert((*it).first);
3196 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3197 _families.erase(*it);
3198 std::vector<std::string> grpNamesToKill;
3199 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3201 std::vector<std::string> tmp;
3202 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3204 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3205 tmp.push_back(*it2);
3210 tmp.push_back((*it).first);
3212 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3216 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3218 std::vector<int> levs=getNonEmptyLevels();
3219 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3220 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3221 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3222 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3223 int nbNodes=m0->getNumberOfNodes();
3224 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3225 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3226 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3227 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3228 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3229 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3230 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3231 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3232 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3233 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3234 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3235 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3236 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3237 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3238 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3239 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3240 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3241 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3242 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3243 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3244 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3245 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3246 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3247 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3248 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3249 m0->setCoords(tmp0->getCoords());
3250 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3251 m1->setCoords(m0->getCoords());
3252 _coords=m0->getCoords(); _coords->incrRef();
3253 // duplication of cells in group 'grpNameM1' on level -1
3254 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3255 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3256 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3257 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3258 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3260 newm1->setName(getName());
3261 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3263 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3264 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3265 newFam->alloc(newm1->getNumberOfCells(),1);
3266 int idd=getMaxFamilyId()+1;
3267 int globStart=0,start=0,end,globEnd;
3268 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3269 for(int i=0;i<nbOfChunks;i++)
3271 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3272 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3274 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3275 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3276 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3281 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3285 newm1->setCoords(getCoords());
3286 setMeshAtLevel(-1,newm1);
3287 setFamilyFieldArr(-1,newFam);
3288 std::string grpName2(grpNameM1); grpName2+="_dup";
3289 addFamily(grpName2,idd);
3290 addFamilyOnGrp(grpName2,grpName2);
3295 int newNbOfNodes=getCoords()->getNumberOfTuples();
3296 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3297 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3298 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3301 nodesDuplicated=nodeIdsToDuplicate.retn();
3302 cellsModified=cellsToModifyConn0.retn();
3303 cellsNotModified=cellsToModifyConn1.retn();
3307 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3308 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3309 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3311 * \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.
3312 * 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.
3314 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3316 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3317 std::vector<int> levs=getNonEmptyLevels();
3319 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3320 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3323 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3325 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3326 std::vector<int> code1=m->getDistributionOfTypes();
3327 end=PutInThirdComponentOfCodeOffset(code1,start);
3328 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3329 bool hasChanged=m->unPolyze();
3330 DataArrayInt *fake=0;
3331 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3332 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3334 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3337 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3338 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3340 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3341 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3342 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3343 setMeshAtLevel(*it,m);
3344 std::vector<int> code2=m->getDistributionOfTypes();
3345 end=PutInThirdComponentOfCodeOffset(code2,start);
3346 newCode.insert(newCode.end(),code2.begin(),code2.end());
3348 if(o2nCellsPart2->isIdentity())
3352 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3353 setFamilyFieldArr(*it,newFamField);
3357 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3358 setRenumFieldArr(*it,newNumField);
3363 newCode.insert(newCode.end(),code1.begin(),code1.end());
3369 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3370 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3371 o2nRenumCell=o2nRenumCellRet.retn();
3376 struct MEDLoaderAccVisit1
3378 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3379 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3380 int _new_nb_of_nodes;
3384 * 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.
3385 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3386 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3387 * -1 values in returned array means that the corresponding old node is no more used.
3389 * \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
3390 * is modified in \a this.
3391 * \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
3394 DataArrayInt *MEDFileUMesh::zipCoords()
3396 const DataArrayDouble *coo=getCoords();
3398 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3399 int nbOfNodes=coo->getNumberOfTuples();
3400 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3401 std::vector<int> neLevs=getNonEmptyLevels();
3402 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3404 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3405 m->computeNodeIdsAlg(nodeIdsInUse);
3407 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3408 if(nbrOfNodesInUse==nbOfNodes)
3410 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3411 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3412 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3413 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3414 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3415 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3416 if((const DataArrayInt *)_fam_coords)
3417 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3418 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3419 if((const DataArrayInt *)_num_coords)
3420 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3421 if((const DataArrayAsciiChar *)_name_coords)
3422 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3423 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3424 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3426 if((MEDFileUMeshSplitL1*)*it)
3427 (*it)->renumberNodesInConn(ret->begin());
3433 * Adds a group of nodes to \a this mesh.
3434 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3435 * The ids should be sorted and different each other (MED file norm).
3436 * \throw If the node coordinates array is not set.
3437 * \throw If \a ids == \c NULL.
3438 * \throw If \a ids->getName() == "".
3439 * \throw If \a ids does not respect the MED file norm.
3440 * \throw If a group with name \a ids->getName() already exists.
3442 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
3444 const DataArrayDouble *coords=_coords;
3446 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3447 int nbOfNodes=coords->getNumberOfTuples();
3448 if(!((DataArrayInt *)_fam_coords))
3449 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3451 addGroupUnderground(true,ids,_fam_coords);
3455 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3456 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3457 * The ids should be sorted and different each other (MED file norm).
3458 * \throw If the node coordinates array is not set.
3459 * \throw If \a ids == \c NULL.
3460 * \throw If \a ids->getName() == "".
3461 * \throw If \a ids does not respect the MED file norm.
3462 * \throw If a group with name \a ids->getName() already exists.
3464 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
3466 std::vector<int> levs=getNonEmptyLevelsExt();
3467 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3469 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3470 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3472 if(meshDimRelToMaxExt==1)
3473 { addNodeGroup(ids); return ; }
3474 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3475 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3476 addGroupUnderground(false,ids,fam);
3480 * \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).
3481 * \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)
3483 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
3486 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3487 std::string grpName(ids->getName());
3489 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3490 ids->checkStrictlyMonotonic(true);
3491 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3492 std::vector<std::string> grpsNames=getGroupsNames();
3493 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3495 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3496 throw INTERP_KERNEL::Exception(oss.str().c_str());
3498 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3499 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3500 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3501 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3502 std::vector<int> familyIds;
3503 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3504 int maxVal=getTheMaxAbsFamilyId()+1;
3505 std::map<std::string,int> families(_families);
3506 std::map<std::string, std::vector<std::string> > groups(_groups);
3507 std::vector<std::string> fams;
3508 bool created(false);
3509 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3511 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3512 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3513 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3514 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3517 bool isFamPresent=false;
3518 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3519 isFamPresent=(*itl)->presenceOfValue(*famId);
3521 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3524 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3525 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3526 fams.push_back(locFamName);
3527 if(existsFamily(*famId))
3529 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3530 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3533 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3537 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3538 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3539 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3540 if(existsFamily(*famId))
3542 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3543 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3548 for(std::size_t i=0;i<familyIds.size();i++)
3550 DataArrayInt *da=idsPerfamiliyIds[i];
3551 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3555 _groups[grpName]=fams;
3559 * Changes a name of a family specified by its id.
3560 * \param [in] id - the id of the family of interest.
3561 * \param [in] newFamName - the new family name.
3562 * \throw If no family with the given \a id exists.
3564 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
3566 std::string oldName=getFamilyNameGivenId(id);
3567 _families.erase(oldName);
3568 _families[newFamName]=id;
3572 * Removes a mesh of a given dimension.
3573 * \param [in] meshDimRelToMax - the relative dimension of interest.
3574 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3576 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
3578 std::vector<int> levSet=getNonEmptyLevels();
3579 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3580 if(it==levSet.end())
3581 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3582 int pos=(-meshDimRelToMax);
3587 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
3588 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3589 * \param [in] m - the new mesh to set.
3590 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3592 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3593 * another node coordinates array.
3594 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3595 * to the existing meshes of other levels of \a this mesh.
3597 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
3599 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
3600 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3604 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3605 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3606 * \param [in] m - the new mesh to set.
3607 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3608 * writing \a this mesh in a MED file.
3609 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3611 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3612 * another node coordinates array.
3613 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3614 * to the existing meshes of other levels of \a this mesh.
3616 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
3618 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
3619 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3622 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
3624 dealWithTinyInfo(m);
3625 std::vector<int> levSet=getNonEmptyLevels();
3626 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3628 if((DataArrayDouble *)_coords==0)
3630 DataArrayDouble *c=m->getCoords();
3635 if(m->getCoords()!=_coords)
3636 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3637 int sz=(-meshDimRelToMax)+1;
3638 if(sz>=(int)_ms.size())
3640 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3644 return _ms[-meshDimRelToMax];
3648 * This method allows to set at once the content of different levels in \a this.
3649 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3651 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3652 * \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.
3653 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3655 * \throw If \a there is a null pointer in \a ms.
3656 * \sa MEDFileUMesh::setMeshAtLevel
3658 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3662 const MEDCouplingUMesh *mRef=ms[0];
3664 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3665 std::string name(mRef->getName());
3666 const DataArrayDouble *coo(mRef->getCoords());
3669 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3671 const MEDCouplingUMesh *cur(*it);
3673 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3674 if(coo!=cur->getCoords())
3675 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3676 int mdim=cur->getMeshDimension();
3677 zeDim=std::max(zeDim,mdim);
3678 if(s.find(mdim)!=s.end())
3679 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3681 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3683 int mdim=(*it)->getMeshDimension();
3684 setName((*it)->getName());
3685 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3691 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3692 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3693 * The given meshes must share the same node coordinates array.
3694 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3695 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3696 * create in \a this mesh.
3697 * \throw If \a ms is empty.
3698 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3699 * to the existing meshes of other levels of \a this mesh.
3700 * \throw If the meshes in \a ms do not share the same node coordinates array.
3701 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3702 * of the given meshes.
3703 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3704 * \throw If names of some meshes in \a ms are equal.
3705 * \throw If \a ms includes a mesh with an empty name.
3707 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3710 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3711 int sz=(-meshDimRelToMax)+1;
3712 if(sz>=(int)_ms.size())
3714 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3715 DataArrayDouble *coo=checkMultiMesh(ms);
3716 if((DataArrayDouble *)_coords==0)
3722 if((DataArrayDouble *)_coords!=coo)
3723 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3724 std::vector<DataArrayInt *> corr;
3725 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3726 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3727 setMeshAtLevel(meshDimRelToMax,m,renum);
3728 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3729 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3733 * Creates groups at a given level in \a this mesh from a sequence of
3734 * meshes each representing a group.
3735 * The given meshes must share the same node coordinates array.
3736 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3737 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3738 * create in \a this mesh.
3739 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3741 * \throw If \a ms is empty.
3742 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3743 * to the existing meshes of other levels of \a this mesh.
3744 * \throw If the meshes in \a ms do not share the same node coordinates array.
3745 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3746 * of the given meshes.
3747 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3748 * \throw If names of some meshes in \a ms are equal.
3749 * \throw If \a ms includes a mesh with an empty name.
3751 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3754 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3755 int sz=(-meshDimRelToMax)+1;
3756 if(sz>=(int)_ms.size())
3758 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3759 DataArrayDouble *coo=checkMultiMesh(ms);
3760 if((DataArrayDouble *)_coords==0)
3766 if((DataArrayDouble *)_coords!=coo)
3767 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3768 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3769 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3771 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3773 DataArrayInt *arr=0;
3774 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3778 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3779 throw INTERP_KERNEL::Exception(oss.str().c_str());
3782 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3783 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3786 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
3788 const DataArrayDouble *ret=ms[0]->getCoords();
3789 int mdim=ms[0]->getMeshDimension();
3790 for(unsigned int i=1;i<ms.size();i++)
3792 ms[i]->checkCoherency();
3793 if(ms[i]->getCoords()!=ret)
3794 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3795 if(ms[i]->getMeshDimension()!=mdim)
3796 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3798 return const_cast<DataArrayDouble *>(ret);
3802 * Sets the family field of a given relative dimension.
3803 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3804 * the family field is set.
3805 * \param [in] famArr - the array of the family field.
3806 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3807 * \throw If \a famArr has an invalid size.
3809 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
3811 if(meshDimRelToMaxExt==1)
3818 DataArrayDouble *coo(_coords);
3820 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3821 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3826 if(meshDimRelToMaxExt>1)
3827 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3828 int traducedRk=-meshDimRelToMaxExt;
3829 if(traducedRk>=(int)_ms.size())
3830 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3831 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3832 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3833 return _ms[traducedRk]->setFamilyArr(famArr);
3837 * Sets the optional numbers of mesh entities of a given dimension.
3838 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3839 * \param [in] renumArr - the array of the numbers.
3840 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3841 * \throw If \a renumArr has an invalid size.
3843 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
3845 if(meshDimRelToMaxExt==1)
3853 DataArrayDouble *coo(_coords);
3855 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3856 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3857 renumArr->incrRef();
3858 _num_coords=renumArr;
3862 if(meshDimRelToMaxExt>1)
3863 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3864 int traducedRk=-meshDimRelToMaxExt;
3865 if(traducedRk>=(int)_ms.size())
3866 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3867 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3868 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3869 return _ms[traducedRk]->setRenumArr(renumArr);
3873 * Sets the optional names of mesh entities of a given dimension.
3874 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3875 * \param [in] nameArr - the array of the names.
3876 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3877 * \throw If \a nameArr has an invalid size.
3879 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
3881 if(meshDimRelToMaxExt==1)
3888 DataArrayDouble *coo(_coords);
3890 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3891 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3893 _name_coords=nameArr;
3896 if(meshDimRelToMaxExt>1)
3897 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3898 int traducedRk=-meshDimRelToMaxExt;
3899 if(traducedRk>=(int)_ms.size())
3900 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3901 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3902 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3903 return _ms[traducedRk]->setNameArr(nameArr);
3906 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3908 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3909 if((const MEDFileUMeshSplitL1 *)(*it))
3910 (*it)->synchronizeTinyInfo(*this);
3914 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3916 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
3918 DataArrayInt *arr=_fam_coords;
3920 arr->changeValue(oldId,newId);
3921 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3923 MEDFileUMeshSplitL1 *sp=(*it);
3926 sp->changeFamilyIdArr(oldId,newId);
3931 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3933 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3934 const DataArrayInt *da(_fam_coords);
3936 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3937 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3939 const MEDFileUMeshSplitL1 *elt(*it);
3942 da=elt->getFamilyField();
3944 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3950 void MEDFileUMesh::computeRevNum() const
3952 if((const DataArrayInt *)_num_coords)
3955 int maxValue=_num_coords->getMaxValue(pos);
3956 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3960 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
3962 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
3965 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildren() const
3967 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
3968 if((const DataArrayInt *)_fam_nodes)
3969 ret.push_back((const DataArrayInt *)_fam_nodes);
3970 if((const DataArrayInt *)_num_nodes)
3971 ret.push_back((const DataArrayInt *)_num_nodes);
3972 if((const DataArrayAsciiChar *)_names_nodes)
3973 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
3974 if((const DataArrayInt *)_fam_cells)
3975 ret.push_back((const DataArrayInt *)_fam_cells);
3976 if((const DataArrayInt *)_num_cells)
3977 ret.push_back((const DataArrayInt *)_num_cells);
3978 if((const DataArrayAsciiChar *)_names_cells)
3979 ret.push_back((const DataArrayAsciiChar *)_names_cells);
3980 if((const DataArrayInt *)_fam_faces)
3981 ret.push_back((const DataArrayInt *)_fam_faces);
3982 if((const DataArrayInt *)_num_faces)
3983 ret.push_back((const DataArrayInt *)_num_faces);
3984 if((const DataArrayInt *)_rev_num_nodes)
3985 if((const DataArrayAsciiChar *)_names_faces)
3986 ret.push_back((const DataArrayAsciiChar *)_names_faces);
3987 ret.push_back((const DataArrayInt *)_rev_num_nodes);
3988 if((const DataArrayInt *)_rev_num_cells)
3989 ret.push_back((const DataArrayInt *)_rev_num_cells);
3993 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
3995 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3996 if((const DataArrayInt *)_fam_nodes)
3998 int val=_fam_nodes->getMaxValue(tmp);
3999 ret=std::max(ret,std::abs(val));
4001 if((const DataArrayInt *)_fam_cells)
4003 int val=_fam_cells->getMaxValue(tmp);
4004 ret=std::max(ret,std::abs(val));
4006 if((const DataArrayInt *)_fam_faces)
4008 int val=_fam_faces->getMaxValue(tmp);
4009 ret=std::max(ret,std::abs(val));
4014 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4016 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4017 if((const DataArrayInt *)_fam_nodes)
4019 int val=_fam_nodes->getMaxValue(tmp);
4020 ret=std::max(ret,val);
4022 if((const DataArrayInt *)_fam_cells)
4024 int val=_fam_cells->getMaxValue(tmp);
4025 ret=std::max(ret,val);
4027 if((const DataArrayInt *)_fam_faces)
4029 int val=_fam_faces->getMaxValue(tmp);
4030 ret=std::max(ret,val);
4035 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4037 int ret=std::numeric_limits<int>::max(),tmp=-1;
4038 if((const DataArrayInt *)_fam_nodes)
4040 int val=_fam_nodes->getMinValue(tmp);
4041 ret=std::min(ret,val);
4043 if((const DataArrayInt *)_fam_cells)
4045 int val=_fam_cells->getMinValue(tmp);
4046 ret=std::min(ret,val);
4048 if((const DataArrayInt *)_fam_faces)
4050 int val=_fam_faces->getMinValue(tmp);
4051 ret=std::min(ret,val);
4056 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4058 if(!MEDFileMesh::isEqual(other,eps,what))
4060 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4063 what="Mesh types differ ! This is structured and other is NOT !";
4066 const DataArrayInt *famc1=_fam_nodes;
4067 const DataArrayInt *famc2=otherC->_fam_nodes;
4068 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4070 what="Mismatch of families arr on nodes ! One is defined and not other !";
4075 bool ret=famc1->isEqual(*famc2);
4078 what="Families arr on nodes differ !";
4083 famc2=otherC->_fam_cells;
4084 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4086 what="Mismatch of families arr on cells ! One is defined and not other !";
4091 bool ret=famc1->isEqual(*famc2);
4094 what="Families arr on cells differ !";
4099 famc2=otherC->_fam_faces;
4100 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4102 what="Mismatch of families arr on faces ! One is defined and not other !";
4107 bool ret=famc1->isEqual(*famc2);
4110 what="Families arr on faces differ !";
4115 famc2=otherC->_num_nodes;
4116 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4118 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4123 bool ret=famc1->isEqual(*famc2);
4126 what="Numbering arr on nodes differ !";
4131 famc2=otherC->_num_cells;
4132 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4134 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4139 bool ret=famc1->isEqual(*famc2);
4142 what="Numbering arr on cells differ !";
4147 famc2=otherC->_num_faces;
4148 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4150 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4155 bool ret=famc1->isEqual(*famc2);
4158 what="Numbering arr on faces differ !";
4162 const DataArrayAsciiChar *d1=_names_cells;
4163 const DataArrayAsciiChar *d2=otherC->_names_cells;
4164 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4166 what="Mismatch of naming arr on cells ! One is defined and not other !";
4171 bool ret=d1->isEqual(*d2);
4174 what="Naming arr on cells differ !";
4179 d2=otherC->_names_faces;
4180 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4182 what="Mismatch of naming arr on faces ! One is defined and not other !";
4187 bool ret=d1->isEqual(*d2);
4190 what="Naming arr on faces differ !";
4195 d2=otherC->_names_nodes;
4196 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4198 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4203 bool ret=d1->isEqual(*d2);
4206 what="Naming arr on nodes differ !";
4213 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4215 MEDFileMesh::clearNonDiscrAttributes();
4216 const DataArrayInt *tmp=_fam_nodes;
4218 (const_cast<DataArrayInt *>(tmp))->setName("");
4221 (const_cast<DataArrayInt *>(tmp))->setName("");
4224 (const_cast<DataArrayInt *>(tmp))->setName("");
4227 (const_cast<DataArrayInt *>(tmp))->setName("");
4230 (const_cast<DataArrayInt *>(tmp))->setName("");
4233 (const_cast<DataArrayInt *>(tmp))->setName("");
4237 * Returns ids of mesh entities contained in given families of a given dimension.
4238 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4240 * \param [in] fams - the names of the families of interest.
4241 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4242 * returned instead of ids.
4243 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4244 * numbers, if available and required, of mesh entities of the families. The caller
4245 * is to delete this array using decrRef() as it is no more needed.
4246 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4248 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4250 std::vector<int> famIds(getFamiliesIds(fams));
4251 switch(meshDimRelToMaxExt)
4255 if((const DataArrayInt *)_fam_nodes)
4257 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4259 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4261 da=_fam_nodes->getIdsEqualList(0,0);
4263 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4268 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4273 if((const DataArrayInt *)_fam_cells)
4275 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4277 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4279 da=_fam_cells->getIdsEqualList(0,0);
4281 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4286 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4291 if((const DataArrayInt *)_fam_faces)
4293 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4295 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4297 da=_fam_faces->getIdsEqualList(0,0);
4299 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
4304 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
4308 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
4313 * Sets the family field of a given relative dimension.
4314 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4315 * the family field is set.
4316 * \param [in] famArr - the array of the family field.
4317 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4318 * \throw If \a famArr has an invalid size.
4319 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
4321 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4323 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4325 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4326 switch(meshDimRelToMaxExt)
4330 int nbCells=mesh->getNumberOfCells();
4331 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4337 int nbNodes=mesh->getNumberOfNodes();
4338 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4344 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4345 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
4350 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
4357 * Sets the optional numbers of mesh entities of a given dimension.
4358 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4359 * \param [in] renumArr - the array of the numbers.
4360 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4361 * \throw If \a renumArr has an invalid size.
4362 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4364 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4366 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4368 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4369 switch(meshDimRelToMaxExt)
4373 int nbCells=mesh->getNumberOfCells();
4374 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4375 _num_cells=renumArr;
4380 int nbNodes=mesh->getNumberOfNodes();
4381 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4382 _num_nodes=renumArr;
4387 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4388 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
4389 _num_faces=renumArr;
4393 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
4396 renumArr->incrRef();
4400 * Sets the optional names of mesh entities of a given dimension.
4401 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4402 * \param [in] nameArr - the array of the names.
4403 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4404 * \throw If \a nameArr has an invalid size.
4406 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4408 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4410 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4411 switch(meshDimRelToMaxExt)
4415 int nbCells=mesh->getNumberOfCells();
4416 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4417 _names_cells=nameArr;
4422 int nbNodes=mesh->getNumberOfNodes();
4423 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4424 _names_nodes=nameArr;
4429 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4430 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
4431 _names_cells=nameArr;
4434 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4441 * Returns the family field for mesh entities of a given dimension.
4442 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4443 * \return const DataArrayInt * - the family field. It is an array of ids of families
4444 * each mesh entity belongs to. It can be \c NULL.
4445 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4447 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
4449 switch(meshDimRelToMaxExt)
4458 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4463 * Returns the optional numbers of mesh entities of a given dimension.
4464 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4465 * \return const DataArrayInt * - the array of the entity numbers.
4466 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4467 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4469 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
4471 switch(meshDimRelToMaxExt)
4480 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4485 * Returns the optional numbers of mesh entities of a given dimension transformed using
4486 * DataArrayInt::invertArrayN2O2O2N().
4487 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4488 * \return const DataArrayInt * - the array of the entity numbers transformed using
4489 * DataArrayInt::invertArrayN2O2O2N().
4490 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4491 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4493 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
4495 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4496 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4497 if(meshDimRelToMaxExt==0)
4499 if((const DataArrayInt *)_num_cells)
4502 int maxValue=_num_cells->getMaxValue(pos);
4503 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4504 return _rev_num_cells;
4507 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4511 if((const DataArrayInt *)_num_nodes)
4514 int maxValue=_num_nodes->getMaxValue(pos);
4515 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4516 return _rev_num_nodes;
4519 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4523 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
4525 switch(meshDimRelToMaxExt)
4528 return _names_cells;
4530 return _names_nodes;
4532 return _names_faces;
4534 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4539 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4540 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4542 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4544 std::vector<int> ret(1);
4549 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4550 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4552 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4554 std::vector<int> ret(2);
4560 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4562 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4564 std::vector<int> ret;
4565 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
4576 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4578 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4580 std::vector<int> ret;
4581 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
4592 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4594 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4596 std::vector<int> ret;
4597 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
4608 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4610 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4612 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4616 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
4618 DataArrayInt *arr=_fam_nodes;
4620 arr->changeValue(oldId,newId);
4623 arr->changeValue(oldId,newId);
4626 arr->changeValue(oldId,newId);
4629 void MEDFileStructuredMesh::deepCpyAttributes()
4631 if((const DataArrayInt*)_fam_nodes)
4632 _fam_nodes=_fam_nodes->deepCpy();
4633 if((const DataArrayInt*)_num_nodes)
4634 _num_nodes=_num_nodes->deepCpy();
4635 if((const DataArrayAsciiChar*)_names_nodes)
4636 _names_nodes=_names_nodes->deepCpy();
4637 if((const DataArrayInt*)_fam_cells)
4638 _fam_cells=_fam_cells->deepCpy();
4639 if((const DataArrayInt*)_num_cells)
4640 _num_cells=_num_cells->deepCpy();
4641 if((const DataArrayAsciiChar*)_names_cells)
4642 _names_cells=_names_cells->deepCpy();
4643 if((const DataArrayInt*)_fam_faces)
4644 _fam_faces=_fam_faces->deepCpy();
4645 if((const DataArrayInt*)_num_faces)
4646 _num_faces=_num_faces->deepCpy();
4647 if((const DataArrayAsciiChar*)_names_faces)
4648 _names_faces=_names_faces->deepCpy();
4649 if((const DataArrayInt*)_rev_num_nodes)
4650 _rev_num_nodes=_rev_num_nodes->deepCpy();
4651 if((const DataArrayInt*)_rev_num_cells)
4652 _rev_num_cells=_rev_num_cells->deepCpy();
4656 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4658 * \return a pointer to cartesian mesh that need to be managed by the caller.
4659 * \warning the returned pointer has to be managed by the caller.
4663 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4664 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
4665 * \param [in] renum - it must be \c false.
4666 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4667 * delete using decrRef() as it is no more needed.
4669 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
4672 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4673 const MEDCouplingStructuredMesh *m(getStructuredMesh());
4674 switch(meshDimRelToMax)
4680 return const_cast<MEDCouplingStructuredMesh *>(m);
4685 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
4686 return m->build1SGTSubLevelMesh();
4689 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4694 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4695 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4696 * \return int - the number of entities.
4697 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4699 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
4701 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4703 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4704 switch(meshDimRelToMaxExt)
4707 return cmesh->getNumberOfCells();
4709 return cmesh->getNumberOfNodes();
4711 return cmesh->getNumberOfCellsOfSubLevelMesh();
4713 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
4717 int MEDFileStructuredMesh::getNumberOfNodes() const
4719 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4721 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4722 return cmesh->getNumberOfNodes();
4725 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
4727 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4729 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
4730 switch(meshDimRelToMax)
4734 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
4739 int mdim(cmesh->getMeshDimension());
4741 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
4742 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
4746 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
4750 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
4752 if(st.getNumberOfItems()!=1)
4753 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 !");
4754 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4755 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4756 if(getNumberOfNodes()!=(int)nodesFetched.size())
4757 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4758 if(st[0].getPflName().empty())
4760 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4763 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
4764 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4765 int sz(nodesFetched.size());
4766 for(const int *work=arr->begin();work!=arr->end();work++)
4768 std::vector<int> conn;
4769 cmesh->getNodeIdsOfCell(*work,conn);
4770 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4771 if(*it>=0 && *it<sz)
4772 nodesFetched[*it]=true;
4774 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4778 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
4780 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
4784 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
4785 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
4787 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4788 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
4790 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4793 if(!mrs || mrs->isCellFamilyFieldReading())
4795 famCells=DataArrayInt::New();
4796 famCells->alloc(nbOfElt,1);
4797 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
4800 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4803 if(!mrs || mrs->isCellNumFieldReading())
4805 numCells=DataArrayInt::New();
4806 numCells->alloc(nbOfElt,1);
4807 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
4810 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4813 if(!mrs || mrs->isCellNameFieldReading())
4815 namesCells=DataArrayAsciiChar::New();
4816 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4817 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
4818 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4823 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4825 setName(strm->getName());
4826 setDescription(strm->getDescription());
4827 setUnivName(strm->getUnivName());
4828 setIteration(strm->getIteration());
4829 setOrder(strm->getOrder());
4830 setTimeValue(strm->getTime());
4831 setTimeUnit(strm->getTimeUnit());
4832 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4833 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4834 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4837 if(!mrs || mrs->isNodeFamilyFieldReading())
4839 int nbNodes(getNumberOfNodes());
4841 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
4842 _fam_nodes=DataArrayInt::New();
4843 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
4844 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...
4845 _fam_nodes->fillWithZero();
4846 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4849 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4852 if(!mrs || mrs->isNodeNumFieldReading())
4854 _num_nodes=DataArrayInt::New();
4855 _num_nodes->alloc(nbOfElt,1);
4856 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4859 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4862 if(!mrs || mrs->isNodeNameFieldReading())
4864 _names_nodes=DataArrayAsciiChar::New();
4865 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4866 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4867 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4870 int meshDim(getStructuredMesh()->getMeshDimension());
4871 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
4873 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
4876 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
4878 int meshDim(getStructuredMesh()->getMeshDimension());
4879 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
4881 if((const DataArrayInt *)_fam_cells)
4882 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4883 if((const DataArrayInt *)_fam_faces)
4884 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
4885 if((const DataArrayInt *)_fam_nodes)
4886 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4887 if((const DataArrayInt *)_num_cells)
4888 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4889 if((const DataArrayInt *)_num_faces)
4890 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
4891 if((const DataArrayInt *)_num_nodes)
4892 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4893 if((const DataArrayAsciiChar *)_names_cells)
4895 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4897 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4898 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4899 throw INTERP_KERNEL::Exception(oss.str().c_str());
4901 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4903 if((const DataArrayAsciiChar *)_names_faces)
4905 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
4907 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
4908 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
4909 throw INTERP_KERNEL::Exception(oss.str().c_str());
4911 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
4913 if((const DataArrayAsciiChar *)_names_nodes)
4915 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4917 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4918 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4919 throw INTERP_KERNEL::Exception(oss.str().c_str());
4921 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4924 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
4928 * Returns an empty instance of MEDFileCMesh.
4929 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4930 * mesh using decrRef() as it is no more needed.
4932 MEDFileCMesh *MEDFileCMesh::New()
4934 return new MEDFileCMesh;
4938 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4939 * file. The first mesh in the file is loaded.
4940 * \param [in] fileName - the name of MED file to read.
4941 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4942 * mesh using decrRef() as it is no more needed.
4943 * \throw If the file is not readable.
4944 * \throw If there is no meshes in the file.
4945 * \throw If the mesh in the file is not a Cartesian one.
4947 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
4949 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4952 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4953 throw INTERP_KERNEL::Exception(oss.str().c_str());
4955 MEDFileUtilities::CheckFileForRead(fileName);
4956 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4958 ParaMEDMEM::MEDCouplingMeshType meshType;
4960 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
4961 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
4965 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4966 * file. The mesh to load is specified by its name and numbers of a time step and an
4968 * \param [in] fileName - the name of MED file to read.
4969 * \param [in] mName - the name of the mesh to read.
4970 * \param [in] dt - the number of a time step.
4971 * \param [in] it - the number of an iteration.
4972 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4973 * mesh using decrRef() as it is no more needed.
4974 * \throw If the file is not readable.
4975 * \throw If there is no mesh with given attributes in the file.
4976 * \throw If the mesh in the file is not a Cartesian one.
4978 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4980 MEDFileUtilities::CheckFileForRead(fileName);
4981 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4982 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4985 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
4987 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
4990 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildren() const
4992 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
4993 if((const MEDCouplingCMesh *)_cmesh)
4994 ret.push_back((const MEDCouplingCMesh *)_cmesh);
4999 * Returns the dimension on cells in \a this mesh.
5000 * \return int - the mesh dimension.
5001 * \throw If there are no cells in this mesh.
5003 int MEDFileCMesh::getMeshDimension() const
5005 if(!((const MEDCouplingCMesh*)_cmesh))
5006 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5007 return _cmesh->getMeshDimension();
5011 * Returns the dimension on nodes in \a this mesh.
5012 * \return int - the space dimension.
5013 * \throw If there are no cells in this mesh.
5015 int MEDFileCMesh::getSpaceDimension() const
5017 if(!((const MEDCouplingCMesh*)_cmesh))
5018 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5019 return _cmesh->getSpaceDimension();
5023 * Returns a string describing \a this mesh.
5024 * \return std::string - the mesh information string.
5026 std::string MEDFileCMesh::simpleRepr() const
5028 return MEDFileStructuredMesh::simpleRepr();
5032 * Returns a full textual description of \a this mesh.
5033 * \return std::string - the string holding the mesh description.
5035 std::string MEDFileCMesh::advancedRepr() const
5037 return simpleRepr();
5040 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5042 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5046 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5048 return new MEDFileCMesh;
5051 MEDFileMesh *MEDFileCMesh::deepCpy() const
5053 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5054 if((const MEDCouplingCMesh*)_cmesh)
5055 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5056 ret->deepCpyAttributes();
5061 * Checks if \a this and another mesh are equal.
5062 * \param [in] other - the mesh to compare with.
5063 * \param [in] eps - a precision used to compare real values.
5064 * \param [in,out] what - the string returning description of unequal data.
5065 * \return bool - \c true if the meshes are equal, \c false, else.
5067 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5069 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5071 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5074 what="Mesh types differ ! This is cartesian and other is NOT !";
5077 clearNonDiscrAttributes();
5078 otherC->clearNonDiscrAttributes();
5079 const MEDCouplingCMesh *coo1=_cmesh;
5080 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5081 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5083 what="Mismatch of cartesian meshes ! One is defined and not other !";
5088 bool ret=coo1->isEqual(coo2,eps);
5091 what="cartesian meshes differ !";
5099 * Clears redundant attributes of incorporated data arrays.
5101 void MEDFileCMesh::clearNonDiscrAttributes() const
5103 MEDFileStructuredMesh::clearNonDiscrAttributes();
5104 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
5107 MEDFileCMesh::MEDFileCMesh()
5111 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5114 loadCMeshFromFile(fid,mName,dt,it,mrs);
5116 catch(INTERP_KERNEL::Exception& e)
5121 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5123 ParaMEDMEM::MEDCouplingMeshType meshType;
5126 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5127 if(meshType!=CARTESIAN)
5129 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
5130 throw INTERP_KERNEL::Exception(oss.str().c_str());
5132 MEDFileCMeshL2 loaderl2;
5133 loaderl2.loadAll(fid,mid,mName,dt,it);
5134 MEDCouplingCMesh *mesh=loaderl2.getMesh();
5137 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5141 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
5142 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
5144 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
5146 synchronizeTinyInfoOnLeaves();
5150 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
5152 synchronizeTinyInfoOnLeaves();
5157 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
5158 * \param [in] m - the new MEDCouplingCMesh to refer to.
5159 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5162 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
5164 dealWithTinyInfo(m);
5170 void MEDFileCMesh::writeLL(med_idt fid) const
5172 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5173 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5174 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5175 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5176 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5177 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5178 int spaceDim(_cmesh->getSpaceDimension());
5179 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5180 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5181 for(int i=0;i<spaceDim;i++)
5183 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
5185 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5186 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
5187 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
5189 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5190 MEDmeshUniversalNameWr(fid,maa);
5191 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
5192 for(int i=0;i<spaceDim;i++)
5194 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
5195 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
5198 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5199 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5202 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
5204 const MEDCouplingCMesh *cmesh=_cmesh;
5207 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
5208 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
5209 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
5210 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
5213 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
5215 return new MEDFileCurveLinearMesh;
5218 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5220 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5223 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5224 throw INTERP_KERNEL::Exception(oss.str().c_str());
5226 MEDFileUtilities::CheckFileForRead(fileName);
5227 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5229 ParaMEDMEM::MEDCouplingMeshType meshType;
5231 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5232 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
5235 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5237 MEDFileUtilities::CheckFileForRead(fileName);
5238 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5239 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
5242 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
5244 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5247 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildren() const
5249 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
5250 if((const MEDCouplingCurveLinearMesh *)_clmesh)
5251 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5255 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5257 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5261 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5263 return new MEDFileCurveLinearMesh;
5266 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5268 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5269 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5270 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5271 ret->deepCpyAttributes();
5275 int MEDFileCurveLinearMesh::getMeshDimension() const
5277 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5278 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5279 return _clmesh->getMeshDimension();
5282 std::string MEDFileCurveLinearMesh::simpleRepr() const
5284 return MEDFileStructuredMesh::simpleRepr();
5287 std::string MEDFileCurveLinearMesh::advancedRepr() const
5289 return simpleRepr();
5292 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5294 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5296 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5299 what="Mesh types differ ! This is curve linear and other is NOT !";
5302 clearNonDiscrAttributes();
5303 otherC->clearNonDiscrAttributes();
5304 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5305 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5306 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5308 what="Mismatch of curve linear meshes ! One is defined and not other !";
5313 bool ret=coo1->isEqual(coo2,eps);
5316 what="curve linear meshes differ !";
5323 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
5325 MEDFileStructuredMesh::clearNonDiscrAttributes();
5326 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
5329 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
5331 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
5334 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
5335 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
5336 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
5337 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
5340 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
5342 synchronizeTinyInfoOnLeaves();
5346 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
5348 dealWithTinyInfo(m);
5354 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
5356 synchronizeTinyInfoOnLeaves();
5360 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
5364 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5367 loadCLMeshFromFile(fid,mName,dt,it,mrs);
5369 catch(INTERP_KERNEL::Exception& e)
5374 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
5376 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5377 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5378 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5379 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5380 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5381 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5382 int spaceDim=_clmesh->getSpaceDimension();
5383 int meshDim=_clmesh->getMeshDimension();
5384 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5385 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5386 const DataArrayDouble *coords=_clmesh->getCoords();
5388 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5389 for(int i=0;i<spaceDim;i++)
5391 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5393 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5394 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
5395 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
5397 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5398 MEDmeshUniversalNameWr(fid,maa);
5399 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5400 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5401 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5403 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5405 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5406 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5409 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5411 ParaMEDMEM::MEDCouplingMeshType meshType;
5414 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5415 if(meshType!=CURVE_LINEAR)
5417 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5418 throw INTERP_KERNEL::Exception(oss.str().c_str());
5420 MEDFileCLMeshL2 loaderl2;
5421 loaderl2.loadAll(fid,mid,mName,dt,it);
5422 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5425 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5428 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5430 return new MEDFileMeshMultiTS;
5433 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
5435 return new MEDFileMeshMultiTS(fileName);
5438 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
5440 return new MEDFileMeshMultiTS(fileName,mName);
5443 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
5445 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5446 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5448 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5449 if((const MEDFileMesh *)*it)
5450 meshOneTs[i]=(*it)->deepCpy();
5451 ret->_mesh_one_ts=meshOneTs;
5455 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
5457 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5460 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildren() const
5462 std::vector<const BigMemoryObject *> ret;
5463 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5465 const MEDFileMesh *cur(*it);
5472 std::string MEDFileMeshMultiTS::getName() const
5474 if(_mesh_one_ts.empty())
5475 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5476 return _mesh_one_ts[0]->getName();
5479 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
5481 std::string oldName(getName());
5482 std::vector< std::pair<std::string,std::string> > v(1);
5483 v[0].first=oldName; v[0].second=newMeshName;
5487 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5490 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5492 MEDFileMesh *cur(*it);
5494 ret=cur->changeNames(modifTab) || ret;
5499 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
5501 if(_mesh_one_ts.empty())
5502 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5503 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5506 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
5509 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5510 _mesh_one_ts.resize(1);
5511 mesh1TimeStep->incrRef();
5512 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5513 _mesh_one_ts[0]=mesh1TimeStep;
5516 void MEDFileMeshMultiTS::write(med_idt fid) const
5518 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5520 (*it)->copyOptionsFrom(*this);
5525 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
5527 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5528 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5529 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5530 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5534 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
5535 {//for the moment to be improved
5536 _mesh_one_ts.resize(1);
5537 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5540 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5544 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
5547 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5550 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5551 throw INTERP_KERNEL::Exception(oss.str().c_str());
5553 MEDFileUtilities::CheckFileForRead(fileName);
5554 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5556 ParaMEDMEM::MEDCouplingMeshType meshType;
5558 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5559 loadFromFile(fileName,ms.front());
5561 catch(INTERP_KERNEL::Exception& e)
5566 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
5569 loadFromFile(fileName,mName);
5571 catch(INTERP_KERNEL::Exception& e)
5576 MEDFileMeshes *MEDFileMeshes::New()
5578 return new MEDFileMeshes;
5581 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
5583 return new MEDFileMeshes(fileName);
5586 void MEDFileMeshes::write(med_idt fid) const
5589 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5591 (*it)->copyOptionsFrom(*this);
5596 void MEDFileMeshes::write(const std::string& fileName, int mode) const
5598 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5599 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5600 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5601 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5606 int MEDFileMeshes::getNumberOfMeshes() const
5608 return _meshes.size();
5611 MEDFileMeshesIterator *MEDFileMeshes::iterator()
5613 return new MEDFileMeshesIterator(this);
5616 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
5618 if(i<0 || i>=(int)_meshes.size())
5620 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5621 throw INTERP_KERNEL::Exception(oss.str().c_str());
5623 return _meshes[i]->getOneTimeStep();
5626 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
5628 std::vector<std::string> ms=getMeshesNames();
5629 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5632 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5633 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5634 throw INTERP_KERNEL::Exception(oss.str().c_str());
5636 return getMeshAtPos((int)std::distance(ms.begin(),it));
5639 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
5641 std::vector<std::string> ret(_meshes.size());
5643 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5645 const MEDFileMeshMultiTS *f=(*it);
5648 ret[i]=f->getName();
5652 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5653 throw INTERP_KERNEL::Exception(oss.str().c_str());
5659 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5662 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5664 MEDFileMeshMultiTS *cur(*it);
5666 ret=cur->changeNames(modifTab) || ret;
5671 void MEDFileMeshes::resize(int newSize)
5673 _meshes.resize(newSize);
5676 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
5679 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5680 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5681 elt->setOneTimeStep(mesh);
5682 _meshes.push_back(elt);
5685 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
5688 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5689 if(i>=(int)_meshes.size())
5690 _meshes.resize(i+1);
5691 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5692 elt->setOneTimeStep(mesh);
5696 void MEDFileMeshes::destroyMeshAtPos(int i)
5698 if(i<0 || i>=(int)_meshes.size())
5700 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5701 throw INTERP_KERNEL::Exception(oss.str().c_str());
5703 _meshes.erase(_meshes.begin()+i);
5706 void MEDFileMeshes::loadFromFile(const std::string& fileName)
5708 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5710 _meshes.resize(ms.size());
5711 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5712 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
5715 MEDFileMeshes::MEDFileMeshes()
5719 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
5722 loadFromFile(fileName);
5724 catch(INTERP_KERNEL::Exception& /*e*/)
5728 MEDFileMeshes *MEDFileMeshes::deepCpy() const
5730 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5732 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5733 if((const MEDFileMeshMultiTS *)*it)
5734 meshes[i]=(*it)->deepCpy();
5735 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5736 ret->_meshes=meshes;
5740 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
5742 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5745 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildren() const
5747 std::vector<const BigMemoryObject *> ret;
5748 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5750 const MEDFileMeshMultiTS *cur(*it);
5757 std::string MEDFileMeshes::simpleRepr() const
5759 std::ostringstream oss;
5760 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5761 simpleReprWithoutHeader(oss);
5765 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5767 int nbOfMeshes=getNumberOfMeshes();
5768 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5769 std::vector<std::string> mns=getMeshesNames();
5770 for(int i=0;i<nbOfMeshes;i++)
5771 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5774 void MEDFileMeshes::checkCoherency() const
5776 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5778 std::set<std::string> s;
5779 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5781 const MEDFileMeshMultiTS *elt=(*it);
5784 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5785 throw INTERP_KERNEL::Exception(oss.str().c_str());
5787 std::size_t sz=s.size();
5788 s.insert(std::string((*it)->getName()));
5791 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5792 throw INTERP_KERNEL::Exception(oss.str().c_str());
5797 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5802 _nb_iter=ms->getNumberOfMeshes();
5806 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5810 MEDFileMesh *MEDFileMeshesIterator::nextt()
5812 if(_iter_id<_nb_iter)
5814 MEDFileMeshes *ms(_ms);
5816 return ms->getMeshAtPos(_iter_id++);