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::getDirectChildrenWithNull() 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;
1987 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
1988 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
1989 * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh.
1990 * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce
1991 * at most the memory consumtion.
1993 * \param [in] fileName - the name of the file.
1994 * \param [in] mName - the name of the mesh to be read.
1995 * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
1996 * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
1997 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
1998 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
1999 * \param [in] mrs - the request for what to be loaded.
2000 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2002 MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2004 MEDFileUtilities::CheckFileForRead(fileName);
2005 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2006 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2010 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2011 * This method is \b NOT wrapped into python.
2013 MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2015 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2016 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2020 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2022 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2023 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2027 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2029 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2030 ret.push_back((const DataArrayDouble*)_coords);
2031 ret.push_back((const DataArrayInt *)_fam_coords);
2032 ret.push_back((const DataArrayInt *)_num_coords);
2033 ret.push_back((const DataArrayInt *)_rev_num_coords);
2034 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2035 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2036 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2040 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2042 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2046 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2048 return new MEDFileUMesh;
2051 MEDFileMesh *MEDFileUMesh::deepCpy() const
2053 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2054 if((const DataArrayDouble*)_coords)
2055 ret->_coords=_coords->deepCpy();
2056 if((const DataArrayInt*)_fam_coords)
2057 ret->_fam_coords=_fam_coords->deepCpy();
2058 if((const DataArrayInt*)_num_coords)
2059 ret->_num_coords=_num_coords->deepCpy();
2060 if((const DataArrayInt*)_rev_num_coords)
2061 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2062 if((const DataArrayAsciiChar*)_name_coords)
2063 ret->_name_coords=_name_coords->deepCpy();
2065 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2067 if((const MEDFileUMeshSplitL1 *)(*it))
2068 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2074 * Checks if \a this and another mesh are equal.
2075 * \param [in] other - the mesh to compare with.
2076 * \param [in] eps - a precision used to compare real values.
2077 * \param [in,out] what - the string returning description of unequal data.
2078 * \return bool - \c true if the meshes are equal, \c false, else.
2080 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2082 if(!MEDFileMesh::isEqual(other,eps,what))
2084 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2087 what="Mesh types differ ! This is unstructured and other is NOT !";
2090 clearNonDiscrAttributes();
2091 otherC->clearNonDiscrAttributes();
2092 const DataArrayDouble *coo1=_coords;
2093 const DataArrayDouble *coo2=otherC->_coords;
2094 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2096 what="Mismatch of coordinates ! One is defined and not other !";
2101 bool ret=coo1->isEqual(*coo2,eps);
2104 what="Coords differ !";
2108 const DataArrayInt *famc1=_fam_coords;
2109 const DataArrayInt *famc2=otherC->_fam_coords;
2110 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2112 what="Mismatch of families arr on nodes ! One is defined and not other !";
2117 bool ret=famc1->isEqual(*famc2);
2120 what="Families arr on node differ !";
2124 const DataArrayInt *numc1=_num_coords;
2125 const DataArrayInt *numc2=otherC->_num_coords;
2126 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2128 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2133 bool ret=numc1->isEqual(*numc2);
2136 what="Numbering arr on node differ !";
2140 const DataArrayAsciiChar *namec1=_name_coords;
2141 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2142 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2144 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2149 bool ret=namec1->isEqual(*namec2);
2152 what="Names arr on node differ !";
2156 if(_ms.size()!=otherC->_ms.size())
2158 what="Number of levels differs !";
2161 std::size_t sz=_ms.size();
2162 for(std::size_t i=0;i<sz;i++)
2164 const MEDFileUMeshSplitL1 *s1=_ms[i];
2165 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2166 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2168 what="Mismatch of presence of sub levels !";
2173 bool ret=s1->isEqual(s2,eps,what);
2182 * Clears redundant attributes of incorporated data arrays.
2184 void MEDFileUMesh::clearNonDiscrAttributes() const
2186 MEDFileMesh::clearNonDiscrAttributes();
2187 const DataArrayDouble *coo1=_coords;
2189 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2190 const DataArrayInt *famc1=_fam_coords;
2192 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2193 const DataArrayInt *numc1=_num_coords;
2195 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2196 const DataArrayAsciiChar *namc1=_name_coords;
2198 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2199 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2201 const MEDFileUMeshSplitL1 *tmp=(*it);
2203 tmp->clearNonDiscrAttributes();
2207 void MEDFileUMesh::setName(const std::string& name)
2209 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2210 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2211 (*it)->setName(name);
2212 MEDFileMesh::setName(name);
2215 MEDFileUMesh::MEDFileUMesh()
2219 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2222 loadUMeshFromFile(fid,mName,dt,it,mrs);
2224 catch(INTERP_KERNEL::Exception& e)
2230 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2231 * See MEDFileUMesh::LoadPartOf for detailed description.
2233 * \sa loadUMeshFromFile
2235 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2237 MEDFileUMeshL2 loaderl2;
2238 ParaMEDMEM::MEDCouplingMeshType meshType;
2241 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2242 if(meshType!=UNSTRUCTURED)
2244 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2245 throw INTERP_KERNEL::Exception(oss.str().c_str());
2247 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2248 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2252 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2254 * \sa loadPartUMeshFromFile
2256 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2258 MEDFileUMeshL2 loaderl2;
2259 ParaMEDMEM::MEDCouplingMeshType meshType;
2262 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2263 if(meshType!=UNSTRUCTURED)
2265 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2266 throw INTERP_KERNEL::Exception(oss.str().c_str());
2268 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2269 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2273 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2275 int lev=loaderl2.getNumberOfLevels();
2277 for(int i=0;i<lev;i++)
2279 if(!loaderl2.emptyLev(i))
2280 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2284 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2286 setName(loaderl2.getName());
2287 setDescription(loaderl2.getDescription());
2288 setUnivName(loaderl2.getUnivName());
2289 setIteration(loaderl2.getIteration());
2290 setOrder(loaderl2.getOrder());
2291 setTimeValue(loaderl2.getTime());
2292 setTimeUnit(loaderl2.getTimeUnit());
2293 _coords=loaderl2.getCoords();
2294 if(!mrs || mrs->isNodeFamilyFieldReading())
2295 _fam_coords=loaderl2.getCoordsFamily();
2296 if(!mrs || mrs->isNodeNumFieldReading())
2297 _num_coords=loaderl2.getCoordsNum();
2298 if(!mrs || mrs->isNodeNameFieldReading())
2299 _name_coords=loaderl2.getCoordsName();
2303 MEDFileUMesh::~MEDFileUMesh()
2307 void MEDFileUMesh::writeLL(med_idt fid) const
2309 const DataArrayDouble *coo=_coords;
2310 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2311 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2312 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2313 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2314 int spaceDim=coo?coo->getNumberOfComponents():0;
2315 int mdim=getMeshDimension();
2316 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2317 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2318 for(int i=0;i<spaceDim;i++)
2320 std::string info=coo->getInfoOnComponent(i);
2322 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2323 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
2324 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
2326 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2327 MEDmeshUniversalNameWr(fid,maa);
2328 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2329 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2330 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2331 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2332 (*it)->write(fid,meshName,mdim);
2333 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2337 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2338 * \return std::vector<int> - a sequence of the relative dimensions.
2340 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2342 std::vector<int> ret;
2344 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2345 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2352 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2353 * \return std::vector<int> - a sequence of the relative dimensions.
2355 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2357 std::vector<int> ret0=getNonEmptyLevels();
2358 if((const DataArrayDouble *) _coords)
2360 std::vector<int> ret(ret0.size()+1);
2362 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2368 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2370 std::vector<int> ret;
2371 const DataArrayInt *famCoo(_fam_coords);
2375 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2377 const MEDFileUMeshSplitL1 *cur(*it);
2379 if(cur->getFamilyField())
2385 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2387 std::vector<int> ret;
2388 const DataArrayInt *numCoo(_num_coords);
2392 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2394 const MEDFileUMeshSplitL1 *cur(*it);
2396 if(cur->getNumberField())
2402 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2404 std::vector<int> ret;
2405 const DataArrayAsciiChar *nameCoo(_name_coords);
2409 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2411 const MEDFileUMeshSplitL1 *cur(*it);
2413 if(cur->getNameField())
2420 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2421 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2422 * \param [in] grp - the name of the group of interest.
2423 * \return std::vector<int> - a sequence of the relative dimensions.
2425 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2427 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2428 return getFamsNonEmptyLevels(fams);
2432 * Returns all relative mesh levels (including nodes) where a given group is defined.
2433 * \param [in] grp - the name of the group of interest.
2434 * \return std::vector<int> - a sequence of the relative dimensions.
2436 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2438 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2439 return getFamsNonEmptyLevelsExt(fams);
2443 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2444 * To include nodes, call getFamNonEmptyLevelsExt() method.
2445 * \param [in] fam - the name of the family of interest.
2446 * \return std::vector<int> - a sequence of the relative dimensions.
2448 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2450 std::vector<std::string> fams(1,std::string(fam));
2451 return getFamsNonEmptyLevels(fams);
2455 * Returns all relative mesh levels (including nodes) where a given family is defined.
2456 * \param [in] fam - the name of the family of interest.
2457 * \return std::vector<int> - a sequence of the relative dimensions.
2459 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2461 std::vector<std::string> fams(1,std::string(fam));
2462 return getFamsNonEmptyLevelsExt(fams);
2466 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2467 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2468 * \param [in] grps - a sequence of names of the groups of interest.
2469 * \return std::vector<int> - a sequence of the relative dimensions.
2471 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2473 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2474 return getFamsNonEmptyLevels(fams);
2478 * Returns all relative mesh levels (including nodes) where given groups are defined.
2479 * \param [in] grps - a sequence of names of the groups of interest.
2480 * \return std::vector<int> - a sequence of the relative dimensions.
2482 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2484 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2485 return getFamsNonEmptyLevelsExt(fams);
2489 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2490 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2491 * \param [in] fams - the name of the family of interest.
2492 * \return std::vector<int> - a sequence of the relative dimensions.
2494 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2496 std::vector<int> ret;
2497 std::vector<int> levs=getNonEmptyLevels();
2498 std::vector<int> famIds=getFamiliesIds(fams);
2499 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2500 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2506 * Returns all relative mesh levels (including nodes) where given families are defined.
2507 * \param [in] fams - the names of the families of interest.
2508 * \return std::vector<int> - a sequence of the relative dimensions.
2510 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2512 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2513 const DataArrayInt *famCoords=_fam_coords;
2516 std::vector<int> famIds=getFamiliesIds(fams);
2517 if(famCoords->presenceOfValue(famIds))
2519 std::vector<int> ret(ret0.size()+1);
2521 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2529 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2530 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2531 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2534 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2536 std::vector<std::string> ret;
2537 std::vector<std::string> allGrps=getGroupsNames();
2538 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2540 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2541 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2547 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2549 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2550 if((const DataArrayInt *)_fam_coords)
2552 int val=_fam_coords->getMaxValue(tmp);
2553 ret=std::max(ret,std::abs(val));
2555 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2557 if((const MEDFileUMeshSplitL1 *)(*it))
2559 const DataArrayInt *da=(*it)->getFamilyField();
2562 int val=da->getMaxValue(tmp);
2563 ret=std::max(ret,std::abs(val));
2570 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2572 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2573 if((const DataArrayInt *)_fam_coords)
2575 int val=_fam_coords->getMaxValue(tmp);
2576 ret=std::max(ret,val);
2578 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2580 if((const MEDFileUMeshSplitL1 *)(*it))
2582 const DataArrayInt *da=(*it)->getFamilyField();
2585 int val=da->getMaxValue(tmp);
2586 ret=std::max(ret,val);
2593 int MEDFileUMesh::getMinFamilyIdInArrays() const
2595 int ret=std::numeric_limits<int>::max(),tmp=-1;
2596 if((const DataArrayInt *)_fam_coords)
2598 int val=_fam_coords->getMinValue(tmp);
2599 ret=std::min(ret,val);
2601 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2603 if((const MEDFileUMeshSplitL1 *)(*it))
2605 const DataArrayInt *da=(*it)->getFamilyField();
2608 int val=da->getMinValue(tmp);
2609 ret=std::min(ret,val);
2617 * Returns the dimension on cells in \a this mesh.
2618 * \return int - the mesh dimension.
2619 * \throw If there are no cells in this mesh.
2621 int MEDFileUMesh::getMeshDimension() const
2624 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2625 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2626 return (*it)->getMeshDimension()+lev;
2627 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2631 * Returns the space dimension of \a this mesh that is equal to number of components in
2632 * the node coordinates array.
2633 * \return int - the space dimension of \a this mesh.
2634 * \throw If the node coordinates array is not available.
2636 int MEDFileUMesh::getSpaceDimension() const
2638 const DataArrayDouble *coo=_coords;
2640 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2641 return coo->getNumberOfComponents();
2645 * Returns a string describing \a this mesh.
2646 * \return std::string - the mesh information string.
2648 std::string MEDFileUMesh::simpleRepr() const
2650 std::ostringstream oss;
2651 oss << MEDFileMesh::simpleRepr();
2652 const DataArrayDouble *coo=_coords;
2653 oss << "- The dimension of the space is ";
2654 static const char MSG1[]= "*** NO COORDS SET ***";
2655 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2657 oss << _coords->getNumberOfComponents() << std::endl;
2659 oss << MSG1 << std::endl;
2660 oss << "- Type of the mesh : UNSTRUCTURED\n";
2661 oss << "- Number of nodes : ";
2663 oss << _coords->getNumberOfTuples() << std::endl;
2665 oss << MSG1 << std::endl;
2666 std::size_t nbOfLev=_ms.size();
2667 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2668 for(std::size_t i=0;i<nbOfLev;i++)
2670 const MEDFileUMeshSplitL1 *lev=_ms[i];
2671 oss << " - Level #" << -((int) i) << " has dimension : ";
2674 oss << lev->getMeshDimension() << std::endl;
2675 lev->simpleRepr(oss);
2678 oss << MSG2 << std::endl;
2680 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2683 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2684 oss << "- Names of coordinates :" << std::endl;
2685 std::vector<std::string> vars=coo->getVarsOnComponent();
2686 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2687 oss << std::endl << "- Units of coordinates : " << std::endl;
2688 std::vector<std::string> units=coo->getUnitsOnComponent();
2689 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2691 oss << std::endl << std::endl;
2697 * Returns a full textual description of \a this mesh.
2698 * \return std::string - the string holding the mesh description.
2700 std::string MEDFileUMesh::advancedRepr() const
2702 return simpleRepr();
2706 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2707 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2708 * \return int - the number of entities.
2709 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2711 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2713 if(meshDimRelToMaxExt==1)
2715 if(!((const DataArrayDouble *)_coords))
2716 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2717 return _coords->getNumberOfTuples();
2719 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2723 * Returns the family field for mesh entities of a given dimension.
2724 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2725 * \return const DataArrayInt * - the family field. It is an array of ids of families
2726 * each mesh entity belongs to. It can be \c NULL.
2728 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2730 if(meshDimRelToMaxExt==1)
2732 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2733 return l1->getFamilyField();
2737 * Returns the optional numbers of mesh entities of a given dimension.
2738 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2739 * \return const DataArrayInt * - the array of the entity numbers.
2740 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2742 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2744 if(meshDimRelToMaxExt==1)
2746 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2747 return l1->getNumberField();
2750 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2752 if(meshDimRelToMaxExt==1)
2753 return _name_coords;
2754 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2755 return l1->getNameField();
2758 int MEDFileUMesh::getNumberOfNodes() const
2760 const DataArrayDouble *coo=_coords;
2762 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2763 return coo->getNumberOfTuples();
2766 bool MEDFileUMesh::hasImplicitPart() const
2771 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
2773 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
2776 void MEDFileUMesh::releaseImplicitPartIfAny() const
2780 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2782 std::size_t sz(st.getNumberOfItems());
2783 for(std::size_t i=0;i<sz;i++)
2785 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2786 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2787 if(st[i].getPflName().empty())
2788 m->computeNodeIdsAlg(nodesFetched);
2791 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2792 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2793 m2->computeNodeIdsAlg(nodesFetched);
2799 * Returns the optional numbers of mesh entities of a given dimension transformed using
2800 * DataArrayInt::invertArrayN2O2O2N().
2801 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2802 * \return const DataArrayInt * - the array of the entity numbers transformed using
2803 * DataArrayInt::invertArrayN2O2O2N().
2804 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2806 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2808 if(meshDimRelToMaxExt==1)
2810 if(!((const DataArrayInt *)_num_coords))
2811 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2812 return _rev_num_coords;
2814 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2815 return l1->getRevNumberField();
2819 * Returns a pointer to the node coordinates array of \a this mesh \b without
2820 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2822 DataArrayDouble *MEDFileUMesh::getCoords() const
2824 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2825 if((DataArrayDouble *)tmp)
2833 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2834 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2836 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2837 * \param [in] grp - the name of the group whose mesh entities are included in the
2839 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2840 * according to the optional numbers of entities, if available.
2841 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2842 * delete this mesh using decrRef() as it is no more needed.
2843 * \throw If the name of a nonexistent group is specified.
2844 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2846 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2848 synchronizeTinyInfoOnLeaves();
2849 std::vector<std::string> tmp(1);
2851 return getGroups(meshDimRelToMaxExt,tmp,renum);
2855 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2856 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2858 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2859 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2861 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2862 * according to the optional numbers of entities, if available.
2863 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2864 * delete this mesh using decrRef() as it is no more needed.
2865 * \throw If a name of a nonexistent group is present in \a grps.
2866 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2868 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2870 synchronizeTinyInfoOnLeaves();
2871 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2872 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2873 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2874 zeRet->setName(grps[0]);
2875 return zeRet.retn();
2879 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2880 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2882 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2883 * \param [in] fam - the name of the family whose mesh entities are included in the
2885 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2886 * according to the optional numbers of entities, if available.
2887 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2888 * delete this mesh using decrRef() as it is no more needed.
2889 * \throw If a name of a nonexistent family is present in \a grps.
2890 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2892 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2894 synchronizeTinyInfoOnLeaves();
2895 std::vector<std::string> tmp(1);
2897 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2901 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2902 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2904 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2905 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2907 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2908 * according to the optional numbers of entities, if available.
2909 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2910 * delete this mesh using decrRef() as it is no more needed.
2911 * \throw If a name of a nonexistent family is present in \a fams.
2912 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2914 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2916 synchronizeTinyInfoOnLeaves();
2917 if(meshDimRelToMaxExt==1)
2919 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2920 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2921 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2925 std::vector<int> famIds=getFamiliesIds(fams);
2926 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2927 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2929 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2931 zeRet=l1->getFamilyPart(0,0,renum);
2932 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2933 zeRet->setName(fams[0]);
2934 return zeRet.retn();
2938 * Returns ids of mesh entities contained in given families of a given dimension.
2939 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2941 * \param [in] fams - the names of the families of interest.
2942 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2943 * returned instead of ids.
2944 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2945 * numbers, if available and required, of mesh entities of the families. The caller
2946 * is to delete this array using decrRef() as it is no more needed.
2947 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2949 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2951 std::vector<int> famIds=getFamiliesIds(fams);
2952 if(meshDimRelToMaxExt==1)
2954 if((const DataArrayInt *)_fam_coords)
2956 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2958 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2960 da=_fam_coords->getIdsEqualList(0,0);
2962 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2967 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2969 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2971 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2973 return l1->getFamilyPartArr(0,0,renum);
2977 * Returns a MEDCouplingUMesh of a given relative dimension.
2978 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2979 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2980 * To build a valid MEDCouplingUMesh from the returned one in this case,
2981 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2982 * \param [in] meshDimRelToMax - the relative dimension of interest.
2983 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2984 * optional numbers of mesh entities.
2985 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2986 * delete using decrRef() as it is no more needed.
2987 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2988 * \sa getGenMeshAtLevel()
2990 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
2992 synchronizeTinyInfoOnLeaves();
2993 if(meshDimRelToMaxExt==1)
2997 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2998 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2999 umesh->setCoords(cc);
3000 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3001 umesh->setName(getName());
3005 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3006 return l1->getWholeMesh(renum);
3010 * Returns a MEDCouplingUMesh of a given relative dimension.
3011 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3012 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3013 * To build a valid MEDCouplingUMesh from the returned one in this case,
3014 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3015 * \param [in] meshDimRelToMax - the relative dimension of interest.
3016 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3017 * optional numbers of mesh entities.
3018 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3019 * delete using decrRef() as it is no more needed.
3020 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3021 * \sa getMeshAtLevel()
3023 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3025 return getMeshAtLevel(meshDimRelToMax,renum);
3028 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3030 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3031 return l1->getDistributionOfTypes();
3035 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3036 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3037 * optional numbers of mesh entities.
3038 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3039 * delete using decrRef() as it is no more needed.
3040 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3042 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3044 return getMeshAtLevel(0,renum);
3048 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3049 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3050 * optional numbers of mesh entities.
3051 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3052 * delete using decrRef() as it is no more needed.
3053 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3055 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3057 return getMeshAtLevel(-1,renum);
3061 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3062 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3063 * optional numbers of mesh entities.
3064 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3065 * delete using decrRef() as it is no more needed.
3066 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3068 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3070 return getMeshAtLevel(-2,renum);
3074 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3075 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3076 * optional numbers of mesh entities.
3077 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3078 * delete using decrRef() as it is no more needed.
3079 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3081 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3083 return getMeshAtLevel(-3,renum);
3087 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3088 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3089 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3090 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3092 void MEDFileUMesh::forceComputationOfParts() const
3094 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3096 const MEDFileUMeshSplitL1 *elt(*it);
3098 elt->forceComputationOfParts();
3103 * This method returns a vector of mesh parts containing each exactly one geometric type.
3104 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3105 * This method is only for memory aware users.
3106 * The returned pointers are **NOT** new object pointer. No need to mange them.
3108 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3110 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3111 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3115 * This method returns the part of \a this having the geometric type \a gt.
3116 * If such part is not existing an exception will be thrown.
3117 * The returned pointer is **NOT** new object pointer. No need to mange it.
3119 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3121 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3122 int lev=(int)cm.getDimension()-getMeshDimension();
3123 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3124 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3128 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3129 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3131 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3133 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3134 return sp->getGeoTypes();
3138 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3139 * \param [in] gt - the geometric type for which the family field is asked.
3140 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3141 * delete using decrRef() as it is no more needed.
3142 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3144 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3146 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3147 int lev=(int)cm.getDimension()-getMeshDimension();
3148 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3149 return sp->extractFamilyFieldOnGeoType(gt);
3153 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3154 * \param [in] gt - the geometric type for which the number field is asked.
3155 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3156 * delete using decrRef() as it is no more needed.
3157 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3159 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3161 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3162 int lev=(int)cm.getDimension()-getMeshDimension();
3163 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3164 return sp->extractNumberFieldOnGeoType(gt);
3167 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3169 if(meshDimRelToMaxExt==1)
3170 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3171 if(meshDimRelToMaxExt>1)
3172 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3173 int tracucedRk=-meshDimRelToMaxExt;
3174 if(tracucedRk>=(int)_ms.size())
3175 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3176 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3177 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3178 return _ms[tracucedRk];
3181 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3183 if(meshDimRelToMaxExt==1)
3184 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3185 if(meshDimRelToMaxExt>1)
3186 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3187 int tracucedRk=-meshDimRelToMaxExt;
3188 if(tracucedRk>=(int)_ms.size())
3189 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3190 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3191 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3192 return _ms[tracucedRk];
3195 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3197 if(-meshDimRelToMax>=(int)_ms.size())
3198 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3200 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3202 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3204 int ref=(*it)->getMeshDimension();
3205 if(ref+i!=meshDim-meshDimRelToMax)
3206 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3212 * Sets the node coordinates array of \a this mesh.
3213 * \param [in] coords - the new node coordinates array.
3214 * \throw If \a coords == \c NULL.
3216 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3219 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3220 coords->checkAllocated();
3221 int nbOfTuples=coords->getNumberOfTuples();
3224 _fam_coords=DataArrayInt::New();
3225 _fam_coords->alloc(nbOfTuples,1);
3226 _fam_coords->fillWithZero();
3227 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3228 if((MEDFileUMeshSplitL1 *)(*it))
3229 (*it)->setCoords(coords);
3233 * Removes all groups of a given dimension in \a this mesh.
3234 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3235 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3237 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3239 if(meshDimRelToMaxExt==1)
3241 if((DataArrayInt *)_fam_coords)
3242 _fam_coords->fillWithZero();
3245 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3246 l1->eraseFamilyField();
3251 * Removes all families with ids not present in the family fields of \a this mesh.
3253 void MEDFileUMesh::optimizeFamilies()
3255 std::vector<int> levs=getNonEmptyLevelsExt();
3256 std::set<int> allFamsIds;
3257 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3259 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3260 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3262 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3265 std::set<std::string> famNamesToKill;
3266 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3268 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3269 famNamesToKill.insert((*it).first);
3271 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3272 _families.erase(*it);
3273 std::vector<std::string> grpNamesToKill;
3274 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3276 std::vector<std::string> tmp;
3277 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3279 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3280 tmp.push_back(*it2);
3285 tmp.push_back((*it).first);
3287 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3291 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3293 std::vector<int> levs=getNonEmptyLevels();
3294 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3295 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3296 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3297 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3298 int nbNodes=m0->getNumberOfNodes();
3299 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3300 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3301 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3302 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3303 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3304 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3305 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3306 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3307 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3308 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3309 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3310 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3311 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3312 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3313 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3314 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3315 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3316 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3317 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3318 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3319 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3320 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3321 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3322 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3323 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3324 m0->setCoords(tmp0->getCoords());
3325 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3326 m1->setCoords(m0->getCoords());
3327 _coords=m0->getCoords(); _coords->incrRef();
3328 // duplication of cells in group 'grpNameM1' on level -1
3329 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3330 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3331 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3332 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3333 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3335 newm1->setName(getName());
3336 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3338 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3339 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3340 newFam->alloc(newm1->getNumberOfCells(),1);
3341 int idd=getMaxFamilyId()+1;
3342 int globStart=0,start=0,end,globEnd;
3343 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3344 for(int i=0;i<nbOfChunks;i++)
3346 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3347 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3349 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3350 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3351 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3356 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3360 newm1->setCoords(getCoords());
3361 setMeshAtLevel(-1,newm1);
3362 setFamilyFieldArr(-1,newFam);
3363 std::string grpName2(grpNameM1); grpName2+="_dup";
3364 addFamily(grpName2,idd);
3365 addFamilyOnGrp(grpName2,grpName2);
3370 int newNbOfNodes=getCoords()->getNumberOfTuples();
3371 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3372 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3373 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3376 nodesDuplicated=nodeIdsToDuplicate.retn();
3377 cellsModified=cellsToModifyConn0.retn();
3378 cellsNotModified=cellsToModifyConn1.retn();
3382 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3383 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3384 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3386 * \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.
3387 * 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.
3389 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3391 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3392 std::vector<int> levs=getNonEmptyLevels();
3394 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3395 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3398 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3400 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3401 std::vector<int> code1=m->getDistributionOfTypes();
3402 end=PutInThirdComponentOfCodeOffset(code1,start);
3403 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3404 bool hasChanged=m->unPolyze();
3405 DataArrayInt *fake=0;
3406 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3407 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3409 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3412 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3413 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3415 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3416 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3417 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3418 setMeshAtLevel(*it,m);
3419 std::vector<int> code2=m->getDistributionOfTypes();
3420 end=PutInThirdComponentOfCodeOffset(code2,start);
3421 newCode.insert(newCode.end(),code2.begin(),code2.end());
3423 if(o2nCellsPart2->isIdentity())
3427 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3428 setFamilyFieldArr(*it,newFamField);
3432 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3433 setRenumFieldArr(*it,newNumField);
3438 newCode.insert(newCode.end(),code1.begin(),code1.end());
3444 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3445 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3446 o2nRenumCell=o2nRenumCellRet.retn();
3451 struct MEDLoaderAccVisit1
3453 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3454 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3455 int _new_nb_of_nodes;
3459 * 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.
3460 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3461 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3462 * -1 values in returned array means that the corresponding old node is no more used.
3464 * \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
3465 * is modified in \a this.
3466 * \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
3469 DataArrayInt *MEDFileUMesh::zipCoords()
3471 const DataArrayDouble *coo=getCoords();
3473 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3474 int nbOfNodes=coo->getNumberOfTuples();
3475 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3476 std::vector<int> neLevs=getNonEmptyLevels();
3477 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3479 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3480 m->computeNodeIdsAlg(nodeIdsInUse);
3482 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3483 if(nbrOfNodesInUse==nbOfNodes)
3485 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3486 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3487 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3488 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3489 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3490 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3491 if((const DataArrayInt *)_fam_coords)
3492 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3493 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3494 if((const DataArrayInt *)_num_coords)
3495 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3496 if((const DataArrayAsciiChar *)_name_coords)
3497 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3498 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3499 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3501 if((MEDFileUMeshSplitL1*)*it)
3502 (*it)->renumberNodesInConn(ret->begin());
3508 * Adds a group of nodes to \a this mesh.
3509 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3510 * The ids should be sorted and different each other (MED file norm).
3511 * \throw If the node coordinates array is not set.
3512 * \throw If \a ids == \c NULL.
3513 * \throw If \a ids->getName() == "".
3514 * \throw If \a ids does not respect the MED file norm.
3515 * \throw If a group with name \a ids->getName() already exists.
3517 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
3519 const DataArrayDouble *coords=_coords;
3521 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3522 int nbOfNodes=coords->getNumberOfTuples();
3523 if(!((DataArrayInt *)_fam_coords))
3524 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3526 addGroupUnderground(true,ids,_fam_coords);
3530 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3531 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3532 * The ids should be sorted and different each other (MED file norm).
3533 * \throw If the node coordinates array is not set.
3534 * \throw If \a ids == \c NULL.
3535 * \throw If \a ids->getName() == "".
3536 * \throw If \a ids does not respect the MED file norm.
3537 * \throw If a group with name \a ids->getName() already exists.
3539 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
3541 std::vector<int> levs=getNonEmptyLevelsExt();
3542 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3544 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3545 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3547 if(meshDimRelToMaxExt==1)
3548 { addNodeGroup(ids); return ; }
3549 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3550 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3551 addGroupUnderground(false,ids,fam);
3555 * \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).
3556 * \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)
3558 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
3561 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3562 std::string grpName(ids->getName());
3564 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3565 ids->checkStrictlyMonotonic(true);
3566 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3567 std::vector<std::string> grpsNames=getGroupsNames();
3568 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3570 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3571 throw INTERP_KERNEL::Exception(oss.str().c_str());
3573 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3574 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3575 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3576 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3577 std::vector<int> familyIds;
3578 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3579 int maxVal=getTheMaxAbsFamilyId()+1;
3580 std::map<std::string,int> families(_families);
3581 std::map<std::string, std::vector<std::string> > groups(_groups);
3582 std::vector<std::string> fams;
3583 bool created(false);
3584 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3586 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3587 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3588 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3589 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3592 bool isFamPresent=false;
3593 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3594 isFamPresent=(*itl)->presenceOfValue(*famId);
3596 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3599 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3600 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3601 fams.push_back(locFamName);
3602 if(existsFamily(*famId))
3604 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3605 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3608 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3612 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3613 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3614 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3615 if(existsFamily(*famId))
3617 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3618 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3623 for(std::size_t i=0;i<familyIds.size();i++)
3625 DataArrayInt *da=idsPerfamiliyIds[i];
3626 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3630 _groups[grpName]=fams;
3634 * Changes a name of a family specified by its id.
3635 * \param [in] id - the id of the family of interest.
3636 * \param [in] newFamName - the new family name.
3637 * \throw If no family with the given \a id exists.
3639 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
3641 std::string oldName=getFamilyNameGivenId(id);
3642 _families.erase(oldName);
3643 _families[newFamName]=id;
3647 * Removes a mesh of a given dimension.
3648 * \param [in] meshDimRelToMax - the relative dimension of interest.
3649 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3651 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
3653 std::vector<int> levSet=getNonEmptyLevels();
3654 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3655 if(it==levSet.end())
3656 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3657 int pos=(-meshDimRelToMax);
3662 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
3663 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3664 * \param [in] m - the new mesh to set.
3665 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3667 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3668 * another node coordinates array.
3669 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3670 * to the existing meshes of other levels of \a this mesh.
3672 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
3674 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
3675 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3679 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3680 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3681 * \param [in] m - the new mesh to set.
3682 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3683 * writing \a this mesh in a MED file.
3684 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3686 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3687 * another node coordinates array.
3688 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3689 * to the existing meshes of other levels of \a this mesh.
3691 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
3693 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
3694 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3697 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
3699 dealWithTinyInfo(m);
3700 std::vector<int> levSet=getNonEmptyLevels();
3701 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3703 if((DataArrayDouble *)_coords==0)
3705 DataArrayDouble *c=m->getCoords();
3710 if(m->getCoords()!=_coords)
3711 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3712 int sz=(-meshDimRelToMax)+1;
3713 if(sz>=(int)_ms.size())
3715 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3719 return _ms[-meshDimRelToMax];
3723 * This method allows to set at once the content of different levels in \a this.
3724 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3726 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3727 * \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.
3728 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3730 * \throw If \a there is a null pointer in \a ms.
3731 * \sa MEDFileUMesh::setMeshAtLevel
3733 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3737 const MEDCouplingUMesh *mRef=ms[0];
3739 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3740 std::string name(mRef->getName());
3741 const DataArrayDouble *coo(mRef->getCoords());
3744 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3746 const MEDCouplingUMesh *cur(*it);
3748 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3749 if(coo!=cur->getCoords())
3750 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3751 int mdim=cur->getMeshDimension();
3752 zeDim=std::max(zeDim,mdim);
3753 if(s.find(mdim)!=s.end())
3754 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3756 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3758 int mdim=(*it)->getMeshDimension();
3759 setName((*it)->getName());
3760 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3766 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3767 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3768 * The given meshes must share the same node coordinates array.
3769 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3770 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3771 * create in \a this mesh.
3772 * \throw If \a ms is empty.
3773 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3774 * to the existing meshes of other levels of \a this mesh.
3775 * \throw If the meshes in \a ms do not share the same node coordinates array.
3776 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3777 * of the given meshes.
3778 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3779 * \throw If names of some meshes in \a ms are equal.
3780 * \throw If \a ms includes a mesh with an empty name.
3782 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3785 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3786 int sz=(-meshDimRelToMax)+1;
3787 if(sz>=(int)_ms.size())
3789 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3790 DataArrayDouble *coo=checkMultiMesh(ms);
3791 if((DataArrayDouble *)_coords==0)
3797 if((DataArrayDouble *)_coords!=coo)
3798 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3799 std::vector<DataArrayInt *> corr;
3800 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3801 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3802 setMeshAtLevel(meshDimRelToMax,m,renum);
3803 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3804 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3808 * Creates groups at a given level in \a this mesh from a sequence of
3809 * meshes each representing a group.
3810 * The given meshes must share the same node coordinates array.
3811 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3812 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3813 * create in \a this mesh.
3814 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3816 * \throw If \a ms is empty.
3817 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3818 * to the existing meshes of other levels of \a this mesh.
3819 * \throw If the meshes in \a ms do not share the same node coordinates array.
3820 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3821 * of the given meshes.
3822 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3823 * \throw If names of some meshes in \a ms are equal.
3824 * \throw If \a ms includes a mesh with an empty name.
3826 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3829 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3830 int sz=(-meshDimRelToMax)+1;
3831 if(sz>=(int)_ms.size())
3833 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3834 DataArrayDouble *coo=checkMultiMesh(ms);
3835 if((DataArrayDouble *)_coords==0)
3841 if((DataArrayDouble *)_coords!=coo)
3842 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3843 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3844 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3846 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3848 DataArrayInt *arr=0;
3849 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3853 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3854 throw INTERP_KERNEL::Exception(oss.str().c_str());
3857 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3858 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3861 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
3863 const DataArrayDouble *ret=ms[0]->getCoords();
3864 int mdim=ms[0]->getMeshDimension();
3865 for(unsigned int i=1;i<ms.size();i++)
3867 ms[i]->checkCoherency();
3868 if(ms[i]->getCoords()!=ret)
3869 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3870 if(ms[i]->getMeshDimension()!=mdim)
3871 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3873 return const_cast<DataArrayDouble *>(ret);
3877 * Sets the family field of a given relative dimension.
3878 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3879 * the family field is set.
3880 * \param [in] famArr - the array of the family field.
3881 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3882 * \throw If \a famArr has an invalid size.
3884 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
3886 if(meshDimRelToMaxExt==1)
3893 DataArrayDouble *coo(_coords);
3895 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3896 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3901 if(meshDimRelToMaxExt>1)
3902 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3903 int traducedRk=-meshDimRelToMaxExt;
3904 if(traducedRk>=(int)_ms.size())
3905 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3906 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3907 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3908 return _ms[traducedRk]->setFamilyArr(famArr);
3912 * Sets the optional numbers of mesh entities of a given dimension.
3913 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3914 * \param [in] renumArr - the array of the numbers.
3915 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3916 * \throw If \a renumArr has an invalid size.
3918 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
3920 if(meshDimRelToMaxExt==1)
3928 DataArrayDouble *coo(_coords);
3930 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3931 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3932 renumArr->incrRef();
3933 _num_coords=renumArr;
3937 if(meshDimRelToMaxExt>1)
3938 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3939 int traducedRk=-meshDimRelToMaxExt;
3940 if(traducedRk>=(int)_ms.size())
3941 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3942 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3943 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3944 return _ms[traducedRk]->setRenumArr(renumArr);
3948 * Sets the optional names of mesh entities of a given dimension.
3949 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3950 * \param [in] nameArr - the array of the names.
3951 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3952 * \throw If \a nameArr has an invalid size.
3954 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
3956 if(meshDimRelToMaxExt==1)
3963 DataArrayDouble *coo(_coords);
3965 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3966 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3968 _name_coords=nameArr;
3971 if(meshDimRelToMaxExt>1)
3972 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3973 int traducedRk=-meshDimRelToMaxExt;
3974 if(traducedRk>=(int)_ms.size())
3975 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3976 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3977 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3978 return _ms[traducedRk]->setNameArr(nameArr);
3981 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3983 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3984 if((const MEDFileUMeshSplitL1 *)(*it))
3985 (*it)->synchronizeTinyInfo(*this);
3989 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3991 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
3993 DataArrayInt *arr=_fam_coords;
3995 arr->changeValue(oldId,newId);
3996 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3998 MEDFileUMeshSplitL1 *sp=(*it);
4001 sp->changeFamilyIdArr(oldId,newId);
4006 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4008 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4009 const DataArrayInt *da(_fam_coords);
4011 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4012 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4014 const MEDFileUMeshSplitL1 *elt(*it);
4017 da=elt->getFamilyField();
4019 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4025 void MEDFileUMesh::computeRevNum() const
4027 if((const DataArrayInt *)_num_coords)
4030 int maxValue=_num_coords->getMaxValue(pos);
4031 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4035 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4037 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4040 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4042 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4043 ret.push_back((const DataArrayInt *)_fam_nodes);
4044 ret.push_back((const DataArrayInt *)_num_nodes);
4045 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4046 ret.push_back((const DataArrayInt *)_fam_cells);
4047 ret.push_back((const DataArrayInt *)_num_cells);
4048 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4049 ret.push_back((const DataArrayInt *)_fam_faces);
4050 ret.push_back((const DataArrayInt *)_num_faces);
4051 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4052 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4053 ret.push_back((const DataArrayInt *)_rev_num_cells);
4054 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4058 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4060 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4061 if((const DataArrayInt *)_fam_nodes)
4063 int val=_fam_nodes->getMaxValue(tmp);
4064 ret=std::max(ret,std::abs(val));
4066 if((const DataArrayInt *)_fam_cells)
4068 int val=_fam_cells->getMaxValue(tmp);
4069 ret=std::max(ret,std::abs(val));
4071 if((const DataArrayInt *)_fam_faces)
4073 int val=_fam_faces->getMaxValue(tmp);
4074 ret=std::max(ret,std::abs(val));
4079 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4081 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4082 if((const DataArrayInt *)_fam_nodes)
4084 int val=_fam_nodes->getMaxValue(tmp);
4085 ret=std::max(ret,val);
4087 if((const DataArrayInt *)_fam_cells)
4089 int val=_fam_cells->getMaxValue(tmp);
4090 ret=std::max(ret,val);
4092 if((const DataArrayInt *)_fam_faces)
4094 int val=_fam_faces->getMaxValue(tmp);
4095 ret=std::max(ret,val);
4100 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4102 int ret=std::numeric_limits<int>::max(),tmp=-1;
4103 if((const DataArrayInt *)_fam_nodes)
4105 int val=_fam_nodes->getMinValue(tmp);
4106 ret=std::min(ret,val);
4108 if((const DataArrayInt *)_fam_cells)
4110 int val=_fam_cells->getMinValue(tmp);
4111 ret=std::min(ret,val);
4113 if((const DataArrayInt *)_fam_faces)
4115 int val=_fam_faces->getMinValue(tmp);
4116 ret=std::min(ret,val);
4121 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4123 if(!MEDFileMesh::isEqual(other,eps,what))
4125 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4128 what="Mesh types differ ! This is structured and other is NOT !";
4131 const DataArrayInt *famc1=_fam_nodes;
4132 const DataArrayInt *famc2=otherC->_fam_nodes;
4133 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4135 what="Mismatch of families arr on nodes ! One is defined and not other !";
4140 bool ret=famc1->isEqual(*famc2);
4143 what="Families arr on nodes differ !";
4148 famc2=otherC->_fam_cells;
4149 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4151 what="Mismatch of families arr on cells ! One is defined and not other !";
4156 bool ret=famc1->isEqual(*famc2);
4159 what="Families arr on cells differ !";
4164 famc2=otherC->_fam_faces;
4165 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4167 what="Mismatch of families arr on faces ! One is defined and not other !";
4172 bool ret=famc1->isEqual(*famc2);
4175 what="Families arr on faces differ !";
4180 famc2=otherC->_num_nodes;
4181 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4183 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4188 bool ret=famc1->isEqual(*famc2);
4191 what="Numbering arr on nodes differ !";
4196 famc2=otherC->_num_cells;
4197 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4199 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4204 bool ret=famc1->isEqual(*famc2);
4207 what="Numbering arr on cells differ !";
4212 famc2=otherC->_num_faces;
4213 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4215 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4220 bool ret=famc1->isEqual(*famc2);
4223 what="Numbering arr on faces differ !";
4227 const DataArrayAsciiChar *d1=_names_cells;
4228 const DataArrayAsciiChar *d2=otherC->_names_cells;
4229 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4231 what="Mismatch of naming arr on cells ! One is defined and not other !";
4236 bool ret=d1->isEqual(*d2);
4239 what="Naming arr on cells differ !";
4244 d2=otherC->_names_faces;
4245 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4247 what="Mismatch of naming arr on faces ! One is defined and not other !";
4252 bool ret=d1->isEqual(*d2);
4255 what="Naming arr on faces differ !";
4260 d2=otherC->_names_nodes;
4261 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4263 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4268 bool ret=d1->isEqual(*d2);
4271 what="Naming arr on nodes differ !";
4278 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4280 MEDFileMesh::clearNonDiscrAttributes();
4281 const DataArrayInt *tmp=_fam_nodes;
4283 (const_cast<DataArrayInt *>(tmp))->setName("");
4286 (const_cast<DataArrayInt *>(tmp))->setName("");
4289 (const_cast<DataArrayInt *>(tmp))->setName("");
4292 (const_cast<DataArrayInt *>(tmp))->setName("");
4295 (const_cast<DataArrayInt *>(tmp))->setName("");
4298 (const_cast<DataArrayInt *>(tmp))->setName("");
4302 * Returns ids of mesh entities contained in given families of a given dimension.
4303 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4305 * \param [in] fams - the names of the families of interest.
4306 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4307 * returned instead of ids.
4308 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4309 * numbers, if available and required, of mesh entities of the families. The caller
4310 * is to delete this array using decrRef() as it is no more needed.
4311 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4313 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4315 std::vector<int> famIds(getFamiliesIds(fams));
4316 switch(meshDimRelToMaxExt)
4320 if((const DataArrayInt *)_fam_nodes)
4322 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4324 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4326 da=_fam_nodes->getIdsEqualList(0,0);
4328 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4333 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4338 if((const DataArrayInt *)_fam_cells)
4340 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4342 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4344 da=_fam_cells->getIdsEqualList(0,0);
4346 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4351 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4356 if((const DataArrayInt *)_fam_faces)
4358 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4360 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4362 da=_fam_faces->getIdsEqualList(0,0);
4364 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
4369 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
4373 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
4375 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
4379 * Sets the family field of a given relative dimension.
4380 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4381 * the family field is set.
4382 * \param [in] famArr - the array of the family field.
4383 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4384 * \throw If \a famArr has an invalid size.
4385 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
4387 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4389 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4391 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4392 switch(meshDimRelToMaxExt)
4396 int nbCells=mesh->getNumberOfCells();
4397 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4403 int nbNodes=mesh->getNumberOfNodes();
4404 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4410 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4411 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
4416 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
4423 * Sets the optional numbers of mesh entities of a given dimension.
4424 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4425 * \param [in] renumArr - the array of the numbers.
4426 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4427 * \throw If \a renumArr has an invalid size.
4428 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4430 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4432 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4434 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4435 switch(meshDimRelToMaxExt)
4439 int nbCells=mesh->getNumberOfCells();
4440 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4441 _num_cells=renumArr;
4446 int nbNodes=mesh->getNumberOfNodes();
4447 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4448 _num_nodes=renumArr;
4453 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4454 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
4455 _num_faces=renumArr;
4459 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
4462 renumArr->incrRef();
4466 * Sets the optional names of mesh entities of a given dimension.
4467 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4468 * \param [in] nameArr - the array of the names.
4469 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4470 * \throw If \a nameArr has an invalid size.
4472 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4474 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4476 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4477 switch(meshDimRelToMaxExt)
4481 int nbCells=mesh->getNumberOfCells();
4482 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4483 _names_cells=nameArr;
4488 int nbNodes=mesh->getNumberOfNodes();
4489 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4490 _names_nodes=nameArr;
4495 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4496 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
4497 _names_cells=nameArr;
4500 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4507 * Returns the family field for mesh entities of a given dimension.
4508 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4509 * \return const DataArrayInt * - the family field. It is an array of ids of families
4510 * each mesh entity belongs to. It can be \c NULL.
4511 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4513 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
4515 switch(meshDimRelToMaxExt)
4524 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4529 * Returns the optional numbers of mesh entities of a given dimension.
4530 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4531 * \return const DataArrayInt * - the array of the entity numbers.
4532 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4533 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4535 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
4537 switch(meshDimRelToMaxExt)
4546 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4551 * Returns the optional numbers of mesh entities of a given dimension transformed using
4552 * DataArrayInt::invertArrayN2O2O2N().
4553 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4554 * \return const DataArrayInt * - the array of the entity numbers transformed using
4555 * DataArrayInt::invertArrayN2O2O2N().
4556 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4557 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4559 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
4561 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4562 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4563 if(meshDimRelToMaxExt==0)
4565 if((const DataArrayInt *)_num_cells)
4568 int maxValue=_num_cells->getMaxValue(pos);
4569 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4570 return _rev_num_cells;
4573 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4577 if((const DataArrayInt *)_num_nodes)
4580 int maxValue=_num_nodes->getMaxValue(pos);
4581 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4582 return _rev_num_nodes;
4585 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4589 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
4591 switch(meshDimRelToMaxExt)
4594 return _names_cells;
4596 return _names_nodes;
4598 return _names_faces;
4600 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4605 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4606 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4608 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4610 std::vector<int> ret(1);
4615 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4616 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4618 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4620 std::vector<int> ret(2);
4626 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4628 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4630 std::vector<int> ret;
4631 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
4642 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4644 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4646 std::vector<int> ret;
4647 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
4658 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4660 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4662 std::vector<int> ret;
4663 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
4674 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4676 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4678 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4682 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
4684 DataArrayInt *arr=_fam_nodes;
4686 arr->changeValue(oldId,newId);
4689 arr->changeValue(oldId,newId);
4692 arr->changeValue(oldId,newId);
4695 void MEDFileStructuredMesh::deepCpyAttributes()
4697 if((const DataArrayInt*)_fam_nodes)
4698 _fam_nodes=_fam_nodes->deepCpy();
4699 if((const DataArrayInt*)_num_nodes)
4700 _num_nodes=_num_nodes->deepCpy();
4701 if((const DataArrayAsciiChar*)_names_nodes)
4702 _names_nodes=_names_nodes->deepCpy();
4703 if((const DataArrayInt*)_fam_cells)
4704 _fam_cells=_fam_cells->deepCpy();
4705 if((const DataArrayInt*)_num_cells)
4706 _num_cells=_num_cells->deepCpy();
4707 if((const DataArrayAsciiChar*)_names_cells)
4708 _names_cells=_names_cells->deepCpy();
4709 if((const DataArrayInt*)_fam_faces)
4710 _fam_faces=_fam_faces->deepCpy();
4711 if((const DataArrayInt*)_num_faces)
4712 _num_faces=_num_faces->deepCpy();
4713 if((const DataArrayAsciiChar*)_names_faces)
4714 _names_faces=_names_faces->deepCpy();
4715 if((const DataArrayInt*)_rev_num_nodes)
4716 _rev_num_nodes=_rev_num_nodes->deepCpy();
4717 if((const DataArrayInt*)_rev_num_cells)
4718 _rev_num_cells=_rev_num_cells->deepCpy();
4722 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4724 * \return a pointer to cartesian mesh that need to be managed by the caller.
4725 * \warning the returned pointer has to be managed by the caller.
4729 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4730 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
4731 * \param [in] renum - it must be \c false.
4732 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4733 * delete using decrRef() as it is no more needed.
4735 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
4738 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4739 const MEDCouplingStructuredMesh *m(getStructuredMesh());
4740 switch(meshDimRelToMax)
4746 return const_cast<MEDCouplingStructuredMesh *>(m);
4751 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
4752 buildMinusOneImplicitPartIfNeeded();
4753 MEDCouplingMesh *ret(_faces_if_necessary);
4759 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4764 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4765 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4766 * \return int - the number of entities.
4767 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4769 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
4771 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4773 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4774 switch(meshDimRelToMaxExt)
4777 return cmesh->getNumberOfCells();
4779 return cmesh->getNumberOfNodes();
4781 return cmesh->getNumberOfCellsOfSubLevelMesh();
4783 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
4787 int MEDFileStructuredMesh::getNumberOfNodes() const
4789 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4791 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4792 return cmesh->getNumberOfNodes();
4795 bool MEDFileStructuredMesh::hasImplicitPart() const
4801 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
4803 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
4805 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
4806 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
4809 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
4810 if(cm.getReverseExtrudedType()!=gt)
4811 throw INTERP_KERNEL::Exception(MSG);
4812 buildImplicitPart();
4813 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
4817 if(gt!=zeFaceMesh->getCellModelEnum())
4818 throw INTERP_KERNEL::Exception(MSG);
4819 return zeFaceMesh->getNumberOfCells();
4823 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
4825 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
4827 buildImplicitPart();
4830 void MEDFileStructuredMesh::buildImplicitPart() const
4832 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
4834 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
4835 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
4838 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
4840 _faces_if_necessary=0;
4844 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
4845 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
4847 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
4849 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
4851 return _faces_if_necessary;
4854 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
4856 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4858 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
4859 switch(meshDimRelToMax)
4863 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
4868 int mdim(cmesh->getMeshDimension());
4870 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
4871 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
4875 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
4879 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
4881 if(st.getNumberOfItems()!=1)
4882 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 !");
4883 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4884 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4885 if(getNumberOfNodes()!=(int)nodesFetched.size())
4886 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4887 if(st[0].getPflName().empty())
4889 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4892 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
4893 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4894 int sz(nodesFetched.size());
4895 for(const int *work=arr->begin();work!=arr->end();work++)
4897 std::vector<int> conn;
4898 cmesh->getNodeIdsOfCell(*work,conn);
4899 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4900 if(*it>=0 && *it<sz)
4901 nodesFetched[*it]=true;
4903 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4907 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
4909 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
4913 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
4914 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
4916 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4917 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
4919 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4922 if(!mrs || mrs->isCellFamilyFieldReading())
4924 famCells=DataArrayInt::New();
4925 famCells->alloc(nbOfElt,1);
4926 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
4929 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4932 if(!mrs || mrs->isCellNumFieldReading())
4934 numCells=DataArrayInt::New();
4935 numCells->alloc(nbOfElt,1);
4936 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
4939 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4942 if(!mrs || mrs->isCellNameFieldReading())
4944 namesCells=DataArrayAsciiChar::New();
4945 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4946 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
4947 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4952 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4954 setName(strm->getName());
4955 setDescription(strm->getDescription());
4956 setUnivName(strm->getUnivName());
4957 setIteration(strm->getIteration());
4958 setOrder(strm->getOrder());
4959 setTimeValue(strm->getTime());
4960 setTimeUnit(strm->getTimeUnit());
4961 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4962 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4963 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4966 if(!mrs || mrs->isNodeFamilyFieldReading())
4968 int nbNodes(getNumberOfNodes());
4970 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
4971 _fam_nodes=DataArrayInt::New();
4972 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
4973 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...
4974 _fam_nodes->fillWithZero();
4975 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4978 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4981 if(!mrs || mrs->isNodeNumFieldReading())
4983 _num_nodes=DataArrayInt::New();
4984 _num_nodes->alloc(nbOfElt,1);
4985 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4988 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4991 if(!mrs || mrs->isNodeNameFieldReading())
4993 _names_nodes=DataArrayAsciiChar::New();
4994 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4995 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4996 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4999 int meshDim(getStructuredMesh()->getMeshDimension());
5000 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5002 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5005 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5007 int meshDim(getStructuredMesh()->getMeshDimension());
5008 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5010 if((const DataArrayInt *)_fam_cells)
5011 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
5012 if((const DataArrayInt *)_fam_faces)
5013 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
5014 if((const DataArrayInt *)_fam_nodes)
5015 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
5016 if((const DataArrayInt *)_num_cells)
5017 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
5018 if((const DataArrayInt *)_num_faces)
5019 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
5020 if((const DataArrayInt *)_num_nodes)
5021 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
5022 if((const DataArrayAsciiChar *)_names_cells)
5024 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5026 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5027 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5028 throw INTERP_KERNEL::Exception(oss.str().c_str());
5030 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
5032 if((const DataArrayAsciiChar *)_names_faces)
5034 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5036 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5037 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5038 throw INTERP_KERNEL::Exception(oss.str().c_str());
5040 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
5042 if((const DataArrayAsciiChar *)_names_nodes)
5044 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5046 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5047 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5048 throw INTERP_KERNEL::Exception(oss.str().c_str());
5050 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
5053 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5057 * Returns an empty instance of MEDFileCMesh.
5058 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5059 * mesh using decrRef() as it is no more needed.
5061 MEDFileCMesh *MEDFileCMesh::New()
5063 return new MEDFileCMesh;
5067 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5068 * file. The first mesh in the file is loaded.
5069 * \param [in] fileName - the name of MED file to read.
5070 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5071 * mesh using decrRef() as it is no more needed.
5072 * \throw If the file is not readable.
5073 * \throw If there is no meshes in the file.
5074 * \throw If the mesh in the file is not a Cartesian one.
5076 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5078 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5081 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5082 throw INTERP_KERNEL::Exception(oss.str().c_str());
5084 MEDFileUtilities::CheckFileForRead(fileName);
5085 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5087 ParaMEDMEM::MEDCouplingMeshType meshType;
5089 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5090 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5094 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5095 * file. The mesh to load is specified by its name and numbers of a time step and an
5097 * \param [in] fileName - the name of MED file to read.
5098 * \param [in] mName - the name of the mesh to read.
5099 * \param [in] dt - the number of a time step.
5100 * \param [in] it - the number of an iteration.
5101 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5102 * mesh using decrRef() as it is no more needed.
5103 * \throw If the file is not readable.
5104 * \throw If there is no mesh with given attributes in the file.
5105 * \throw If the mesh in the file is not a Cartesian one.
5107 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5109 MEDFileUtilities::CheckFileForRead(fileName);
5110 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5111 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5114 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5116 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5119 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5121 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5122 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5127 * Returns the dimension on cells in \a this mesh.
5128 * \return int - the mesh dimension.
5129 * \throw If there are no cells in this mesh.
5131 int MEDFileCMesh::getMeshDimension() const
5133 if(!((const MEDCouplingCMesh*)_cmesh))
5134 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5135 return _cmesh->getMeshDimension();
5139 * Returns the dimension on nodes in \a this mesh.
5140 * \return int - the space dimension.
5141 * \throw If there are no cells in this mesh.
5143 int MEDFileCMesh::getSpaceDimension() const
5145 if(!((const MEDCouplingCMesh*)_cmesh))
5146 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5147 return _cmesh->getSpaceDimension();
5151 * Returns a string describing \a this mesh.
5152 * \return std::string - the mesh information string.
5154 std::string MEDFileCMesh::simpleRepr() const
5156 return MEDFileStructuredMesh::simpleRepr();
5160 * Returns a full textual description of \a this mesh.
5161 * \return std::string - the string holding the mesh description.
5163 std::string MEDFileCMesh::advancedRepr() const
5165 return simpleRepr();
5168 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5170 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5174 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5176 return new MEDFileCMesh;
5179 MEDFileMesh *MEDFileCMesh::deepCpy() const
5181 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5182 if((const MEDCouplingCMesh*)_cmesh)
5183 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5184 ret->deepCpyAttributes();
5189 * Checks if \a this and another mesh are equal.
5190 * \param [in] other - the mesh to compare with.
5191 * \param [in] eps - a precision used to compare real values.
5192 * \param [in,out] what - the string returning description of unequal data.
5193 * \return bool - \c true if the meshes are equal, \c false, else.
5195 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5197 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5199 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5202 what="Mesh types differ ! This is cartesian and other is NOT !";
5205 clearNonDiscrAttributes();
5206 otherC->clearNonDiscrAttributes();
5207 const MEDCouplingCMesh *coo1=_cmesh;
5208 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5209 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5211 what="Mismatch of cartesian meshes ! One is defined and not other !";
5216 bool ret=coo1->isEqual(coo2,eps);
5219 what="cartesian meshes differ !";
5227 * Clears redundant attributes of incorporated data arrays.
5229 void MEDFileCMesh::clearNonDiscrAttributes() const
5231 MEDFileStructuredMesh::clearNonDiscrAttributes();
5232 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
5235 MEDFileCMesh::MEDFileCMesh()
5239 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5242 loadCMeshFromFile(fid,mName,dt,it,mrs);
5244 catch(INTERP_KERNEL::Exception& e)
5249 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5251 ParaMEDMEM::MEDCouplingMeshType meshType;
5254 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5255 if(meshType!=CARTESIAN)
5257 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
5258 throw INTERP_KERNEL::Exception(oss.str().c_str());
5260 MEDFileCMeshL2 loaderl2;
5261 loaderl2.loadAll(fid,mid,mName,dt,it);
5262 MEDCouplingCMesh *mesh=loaderl2.getMesh();
5265 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5269 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
5270 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
5272 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
5274 synchronizeTinyInfoOnLeaves();
5278 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
5280 synchronizeTinyInfoOnLeaves();
5285 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
5286 * \param [in] m - the new MEDCouplingCMesh to refer to.
5287 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5290 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
5292 dealWithTinyInfo(m);
5298 void MEDFileCMesh::writeLL(med_idt fid) const
5300 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5301 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5302 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5303 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5304 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5305 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5306 int spaceDim(_cmesh->getSpaceDimension());
5307 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5308 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5309 for(int i=0;i<spaceDim;i++)
5311 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
5313 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5314 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
5315 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
5317 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5318 MEDmeshUniversalNameWr(fid,maa);
5319 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
5320 for(int i=0;i<spaceDim;i++)
5322 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
5323 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
5326 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5327 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5330 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
5332 const MEDCouplingCMesh *cmesh=_cmesh;
5335 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
5336 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
5337 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
5338 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
5341 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
5343 return new MEDFileCurveLinearMesh;
5346 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5348 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5351 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5352 throw INTERP_KERNEL::Exception(oss.str().c_str());
5354 MEDFileUtilities::CheckFileForRead(fileName);
5355 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5357 ParaMEDMEM::MEDCouplingMeshType meshType;
5359 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5360 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
5363 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5365 MEDFileUtilities::CheckFileForRead(fileName);
5366 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5367 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
5370 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
5372 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5375 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
5377 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5378 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5382 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5384 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5388 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5390 return new MEDFileCurveLinearMesh;
5393 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5395 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5396 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5397 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5398 ret->deepCpyAttributes();
5402 int MEDFileCurveLinearMesh::getMeshDimension() const
5404 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5405 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5406 return _clmesh->getMeshDimension();
5409 std::string MEDFileCurveLinearMesh::simpleRepr() const
5411 return MEDFileStructuredMesh::simpleRepr();
5414 std::string MEDFileCurveLinearMesh::advancedRepr() const
5416 return simpleRepr();
5419 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5421 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5423 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5426 what="Mesh types differ ! This is curve linear and other is NOT !";
5429 clearNonDiscrAttributes();
5430 otherC->clearNonDiscrAttributes();
5431 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5432 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5433 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5435 what="Mismatch of curve linear meshes ! One is defined and not other !";
5440 bool ret=coo1->isEqual(coo2,eps);
5443 what="curve linear meshes differ !";
5450 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
5452 MEDFileStructuredMesh::clearNonDiscrAttributes();
5453 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
5456 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
5458 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
5461 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
5462 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
5463 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
5464 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
5467 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
5469 synchronizeTinyInfoOnLeaves();
5473 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
5475 dealWithTinyInfo(m);
5481 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
5483 synchronizeTinyInfoOnLeaves();
5487 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
5491 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5494 loadCLMeshFromFile(fid,mName,dt,it,mrs);
5496 catch(INTERP_KERNEL::Exception& e)
5501 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
5503 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5504 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5505 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5506 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5507 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5508 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5509 int spaceDim=_clmesh->getSpaceDimension();
5510 int meshDim=_clmesh->getMeshDimension();
5511 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5512 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5513 const DataArrayDouble *coords=_clmesh->getCoords();
5515 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5516 for(int i=0;i<spaceDim;i++)
5518 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5520 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5521 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
5522 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
5524 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5525 MEDmeshUniversalNameWr(fid,maa);
5526 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5527 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5528 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5530 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5532 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5533 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5536 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5538 ParaMEDMEM::MEDCouplingMeshType meshType;
5541 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5542 if(meshType!=CURVE_LINEAR)
5544 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5545 throw INTERP_KERNEL::Exception(oss.str().c_str());
5547 MEDFileCLMeshL2 loaderl2;
5548 loaderl2.loadAll(fid,mid,mName,dt,it);
5549 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5552 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5555 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5557 return new MEDFileMeshMultiTS;
5560 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
5562 return new MEDFileMeshMultiTS(fileName);
5565 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
5567 return new MEDFileMeshMultiTS(fileName,mName);
5570 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
5572 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5573 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5575 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5576 if((const MEDFileMesh *)*it)
5577 meshOneTs[i]=(*it)->deepCpy();
5578 ret->_mesh_one_ts=meshOneTs;
5582 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
5584 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5587 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
5589 std::vector<const BigMemoryObject *> ret;
5590 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5591 ret.push_back((const MEDFileMesh *)*it);
5595 std::string MEDFileMeshMultiTS::getName() const
5597 if(_mesh_one_ts.empty())
5598 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5599 return _mesh_one_ts[0]->getName();
5602 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
5604 std::string oldName(getName());
5605 std::vector< std::pair<std::string,std::string> > v(1);
5606 v[0].first=oldName; v[0].second=newMeshName;
5610 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5613 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5615 MEDFileMesh *cur(*it);
5617 ret=cur->changeNames(modifTab) || ret;
5622 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
5624 if(_mesh_one_ts.empty())
5625 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5626 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5629 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
5632 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5633 _mesh_one_ts.resize(1);
5634 mesh1TimeStep->incrRef();
5635 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5636 _mesh_one_ts[0]=mesh1TimeStep;
5639 void MEDFileMeshMultiTS::write(med_idt fid) const
5641 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5643 (*it)->copyOptionsFrom(*this);
5648 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
5650 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5651 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5652 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5653 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5657 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
5658 {//for the moment to be improved
5659 _mesh_one_ts.resize(1);
5660 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5663 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5667 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
5670 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5673 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5674 throw INTERP_KERNEL::Exception(oss.str().c_str());
5676 MEDFileUtilities::CheckFileForRead(fileName);
5677 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5679 ParaMEDMEM::MEDCouplingMeshType meshType;
5681 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5682 loadFromFile(fileName,ms.front());
5684 catch(INTERP_KERNEL::Exception& e)
5689 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
5692 loadFromFile(fileName,mName);
5694 catch(INTERP_KERNEL::Exception& e)
5699 MEDFileMeshes *MEDFileMeshes::New()
5701 return new MEDFileMeshes;
5704 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
5706 return new MEDFileMeshes(fileName);
5709 void MEDFileMeshes::write(med_idt fid) const
5712 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5714 (*it)->copyOptionsFrom(*this);
5719 void MEDFileMeshes::write(const std::string& fileName, int mode) const
5721 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5722 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5723 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5724 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5729 int MEDFileMeshes::getNumberOfMeshes() const
5731 return _meshes.size();
5734 MEDFileMeshesIterator *MEDFileMeshes::iterator()
5736 return new MEDFileMeshesIterator(this);
5739 /** Return a borrowed reference (caller is not responsible) */
5740 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
5742 if(i<0 || i>=(int)_meshes.size())
5744 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5745 throw INTERP_KERNEL::Exception(oss.str().c_str());
5747 return _meshes[i]->getOneTimeStep();
5750 /** Return a borrowed reference (caller is not responsible) */
5751 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
5753 std::vector<std::string> ms=getMeshesNames();
5754 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5757 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5758 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5759 throw INTERP_KERNEL::Exception(oss.str().c_str());
5761 return getMeshAtPos((int)std::distance(ms.begin(),it));
5764 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
5766 std::vector<std::string> ret(_meshes.size());
5768 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5770 const MEDFileMeshMultiTS *f=(*it);
5773 ret[i]=f->getName();
5777 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5778 throw INTERP_KERNEL::Exception(oss.str().c_str());
5784 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5787 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5789 MEDFileMeshMultiTS *cur(*it);
5791 ret=cur->changeNames(modifTab) || ret;
5796 void MEDFileMeshes::resize(int newSize)
5798 _meshes.resize(newSize);
5801 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
5804 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5805 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5806 elt->setOneTimeStep(mesh);
5807 _meshes.push_back(elt);
5810 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
5813 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5814 if(i>=(int)_meshes.size())
5815 _meshes.resize(i+1);
5816 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5817 elt->setOneTimeStep(mesh);
5821 void MEDFileMeshes::destroyMeshAtPos(int i)
5823 if(i<0 || i>=(int)_meshes.size())
5825 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5826 throw INTERP_KERNEL::Exception(oss.str().c_str());
5828 _meshes.erase(_meshes.begin()+i);
5831 void MEDFileMeshes::loadFromFile(const std::string& fileName)
5833 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5835 _meshes.resize(ms.size());
5836 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5837 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
5840 MEDFileMeshes::MEDFileMeshes()
5844 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
5847 loadFromFile(fileName);
5849 catch(INTERP_KERNEL::Exception& /*e*/)
5853 MEDFileMeshes *MEDFileMeshes::deepCpy() const
5855 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5857 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5858 if((const MEDFileMeshMultiTS *)*it)
5859 meshes[i]=(*it)->deepCpy();
5860 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5861 ret->_meshes=meshes;
5865 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
5867 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5870 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
5872 std::vector<const BigMemoryObject *> ret;
5873 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5874 ret.push_back((const MEDFileMeshMultiTS *)*it);
5878 std::string MEDFileMeshes::simpleRepr() const
5880 std::ostringstream oss;
5881 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5882 simpleReprWithoutHeader(oss);
5886 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5888 int nbOfMeshes=getNumberOfMeshes();
5889 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5890 std::vector<std::string> mns=getMeshesNames();
5891 for(int i=0;i<nbOfMeshes;i++)
5892 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5895 void MEDFileMeshes::checkCoherency() const
5897 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5899 std::set<std::string> s;
5900 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5902 const MEDFileMeshMultiTS *elt=(*it);
5905 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5906 throw INTERP_KERNEL::Exception(oss.str().c_str());
5908 std::size_t sz=s.size();
5909 s.insert(std::string((*it)->getName()));
5912 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5913 throw INTERP_KERNEL::Exception(oss.str().c_str());
5918 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5923 _nb_iter=ms->getNumberOfMeshes();
5927 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5931 MEDFileMesh *MEDFileMeshesIterator::nextt()
5933 if(_iter_id<_nb_iter)
5935 MEDFileMeshes *ms(_ms);
5937 return ms->getMeshAtPos(_iter_id++);