1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileUtilities.hxx"
23 #include "MEDFileFieldOverView.hxx"
24 #include "MEDFileField.hxx"
25 #include "MEDLoader.hxx"
26 #include "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 * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever
665 * this family is orphan or not.
667 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
669 void MEDFileMesh::removeFamiliesReferedByNoGroups()
671 std::map<std::string,int> fams;
672 std::set<std::string> sfams;
673 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
674 sfams.insert((*it).first);
675 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
676 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
678 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
679 if(*it!=DFT_FAM_NAME)
680 _families.erase(*it);
684 * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities
685 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
686 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
688 * \sa MEDFileMesh::removeOrphanFamilies
690 void MEDFileMesh::rearrangeFamilies()
692 checkOrphanFamilyZero();
693 removeFamiliesReferedByNoGroups();
695 std::vector<int> levels(getNonEmptyLevelsExt());
696 std::set<int> idsRefed;
697 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
698 idsRefed.insert((*it).second);
699 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
701 const DataArrayInt *fams(0);
704 fams=getFamilyFieldAtLevel(*it);
706 catch(INTERP_KERNEL::Exception& e) { }
709 std::vector<bool> v(fams->getNumberOfTuples(),false);
710 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
711 fams->switchOnTupleEqualTo(*pt,v);
712 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
713 if(!unfetchedIds->empty())
715 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
716 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
717 setFamilyFieldArr(*it,newFams);
720 removeOrphanFamilies();
724 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
726 void MEDFileMesh::checkOrphanFamilyZero() const
728 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
730 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
732 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
733 throw INTERP_KERNEL::Exception(oss.str().c_str());
739 * Renames a group in \a this mesh.
740 * \param [in] oldName - a current name of the group to rename.
741 * \param [in] newName - a new group name.
742 * \throw If no group named \a oldName exists in \a this mesh.
743 * \throw If a group named \a newName already exists.
745 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
747 std::string oname(oldName);
748 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
749 std::vector<std::string> grps=getGroupsNames();
750 if(it==_groups.end())
752 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
753 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
754 throw INTERP_KERNEL::Exception(oss.str().c_str());
756 std::string nname(newName);
757 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
758 if(it2!=_groups.end())
760 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
761 throw INTERP_KERNEL::Exception(oss.str().c_str());
763 std::vector<std::string> cpy=(*it).second;
765 _groups[newName]=cpy;
769 * Changes an id of a family in \a this mesh.
770 * This method calls changeFamilyIdArr().
771 * \param [in] oldId - a current id of the family.
772 * \param [in] newId - a new family id.
774 void MEDFileMesh::changeFamilyId(int oldId, int newId)
776 changeFamilyIdArr(oldId,newId);
777 std::map<std::string,int> fam2;
778 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
780 if((*it).second==oldId)
781 fam2[(*it).first]=newId;
783 fam2[(*it).first]=(*it).second;
789 * Renames a family in \a this mesh.
790 * \param [in] oldName - a current name of the family to rename.
791 * \param [in] newName - a new family name.
792 * \throw If no family named \a oldName exists in \a this mesh.
793 * \throw If a family named \a newName already exists.
795 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
797 std::string oname(oldName);
798 std::map<std::string, int >::iterator it=_families.find(oname);
799 std::vector<std::string> fams=getFamiliesNames();
800 if(it==_families.end())
802 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
803 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
804 throw INTERP_KERNEL::Exception(oss.str().c_str());
806 std::string nname(newName);
807 std::map<std::string, int >::iterator it2=_families.find(nname);
808 if(it2!=_families.end())
810 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
811 throw INTERP_KERNEL::Exception(oss.str().c_str());
813 int cpy=(*it).second;
815 _families[newName]=cpy;
816 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
818 std::vector<std::string>& v=(*it3).second;
819 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
826 * Checks if \a this and another mesh contains the same families.
827 * \param [in] other - the mesh to compare with \a this one.
828 * \param [in,out] what - an unused parameter.
829 * \return bool - \c true if number of families and their ids are the same in the two
830 * meshes. Families with the id == \c 0 are not considered.
832 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
834 if(_families==other->_families)
836 std::map<std::string,int> fam0;
837 std::map<std::string,int> fam1;
838 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
840 fam0[(*it).first]=(*it).second;
841 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
843 fam1[(*it).first]=(*it).second;
848 * Checks if \a this and another mesh contains the same groups.
849 * \param [in] other - the mesh to compare with \a this one.
850 * \param [in,out] what - a string describing a difference of groups of the two meshes
851 * in case if this method returns \c false.
852 * \return bool - \c true if number of groups and families constituting them are the
853 * same in the two meshes.
855 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
857 if(_groups==other->_groups)
860 std::size_t sz=_groups.size();
861 if(sz!=other->_groups.size())
863 what="Groups differ because not same number !\n";
868 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
869 for(std::size_t i=0;i<sz && ret;i++,it1++)
871 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
872 if(it2!=other->_groups.end())
874 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
875 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
881 what="A group in first mesh exists not in other !\n";
887 std::ostringstream oss; oss << "Groups description differs :\n";
888 oss << "First group description :\n";
889 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
891 oss << " Group \"" << (*it).first << "\" on following families :\n";
892 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
893 oss << " \"" << *it2 << "\n";
895 oss << "Second group description :\n";
896 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
898 oss << " Group \"" << (*it).first << "\" on following families :\n";
899 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
900 oss << " \"" << *it2 << "\n";
908 * Checks if a group with a given name exists in \a this mesh.
909 * \param [in] groupName - the group name.
910 * \return bool - \c true the group \a groupName exists in \a this mesh.
912 bool MEDFileMesh::existsGroup(const std::string& groupName) const
914 std::string grpName(groupName);
915 return _groups.find(grpName)!=_groups.end();
919 * Checks if a family with a given id exists in \a this mesh.
920 * \param [in] famId - the family id.
921 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
923 bool MEDFileMesh::existsFamily(int famId) const
925 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
926 if((*it2).second==famId)
932 * Checks if a family with a given name exists in \a this mesh.
933 * \param [in] familyName - the family name.
934 * \return bool - \c true the family \a familyName exists in \a this mesh.
936 bool MEDFileMesh::existsFamily(const std::string& familyName) const
938 std::string fname(familyName);
939 return _families.find(fname)!=_families.end();
943 * Sets an id of a family.
944 * \param [in] familyName - the family name.
945 * \param [in] id - a new id of the family.
947 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
949 std::string fname(familyName);
953 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
955 std::string fname(familyName);
956 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
959 if((*it).first!=familyName)
961 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
962 throw INTERP_KERNEL::Exception(oss.str().c_str());
969 * Adds a family to \a this mesh.
970 * \param [in] familyName - a name of the family.
971 * \param [in] famId - an id of the family.
972 * \throw If a family with the same name or id already exists in \a this mesh.
974 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
976 std::string fname(familyName);
977 std::map<std::string,int>::const_iterator it=_families.find(fname);
978 if(it==_families.end())
980 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
981 if((*it2).second==famId)
983 std::ostringstream oss;
984 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
985 throw INTERP_KERNEL::Exception(oss.str().c_str());
987 _families[fname]=famId;
991 if((*it).second!=famId)
993 std::ostringstream oss;
994 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
995 throw INTERP_KERNEL::Exception(oss.str().c_str());
1001 * Creates a group including all mesh entities of given dimension.
1002 * \warning This method does \b not guarantee that the created group includes mesh
1003 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1004 * present in family fields of different dimensions. To assure this, call
1005 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1006 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1008 * \param [in] groupName - a name of the new group.
1009 * \throw If a group named \a groupName already exists.
1010 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1011 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1013 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1015 std::string grpName(groupName);
1016 std::vector<int> levs=getNonEmptyLevelsExt();
1017 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1019 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1020 oss << "Available relative ext levels are : ";
1021 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1022 throw INTERP_KERNEL::Exception(oss.str().c_str());
1024 if(existsGroup(groupName))
1026 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1027 oss << "Already existing groups are : ";
1028 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1029 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1030 throw INTERP_KERNEL::Exception(oss.str().c_str());
1032 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1034 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1035 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1036 std::vector<std::string> familiesOnWholeGroup;
1037 for(const int *it=famIds->begin();it!=famIds->end();it++)
1040 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1042 _groups[grpName]=familiesOnWholeGroup;
1046 * Ensures that given family ids do not present in family fields of dimensions different
1047 * than given ones. If a family id is present in the family fields of dimensions different
1048 * than the given ones, a new family is created and the whole data is updated accordingly.
1049 * \param [in] famIds - a sequence of family ids to check.
1050 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1051 * famIds should exclusively belong.
1052 * \return bool - \c true if no modification is done in \a this mesh by this method.
1054 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1056 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1057 std::vector<int> levs=getNonEmptyLevelsExt();
1058 std::set<int> levs2(levs.begin(),levs.end());
1059 std::vector<int> levsToTest;
1060 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1061 std::set<int> famIds2(famIds.begin(),famIds.end());
1064 if(!_families.empty())
1065 maxFamId=getMaxFamilyId()+1;
1066 std::vector<std::string> allFams=getFamiliesNames();
1067 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1069 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1072 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1073 std::vector<int> tmp;
1074 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1075 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1078 std::string famName=getFamilyNameGivenId(*it2);
1079 std::ostringstream oss; oss << "Family_" << maxFamId;
1080 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1081 addFamilyOnAllGroupsHaving(famName,zeName);
1082 _families[zeName]=maxFamId;
1083 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1092 * Adds a family to a given group in \a this mesh. If the group with a given name does
1093 * not exist, it is created.
1094 * \param [in] grpName - the name of the group to add the family in.
1095 * \param [in] famName - the name of the family to add to the group named \a grpName.
1096 * \throw If \a grpName or \a famName is an empty string.
1097 * \throw If no family named \a famName is present in \a this mesh.
1099 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1101 std::string grpn(grpName);
1102 std::string famn(famName);
1103 if(grpn.empty() || famn.empty())
1104 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1105 std::vector<std::string> fams=getFamiliesNames();
1106 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1108 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1109 oss << "Create this family or choose an existing one ! Existing fams are : ";
1110 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1111 throw INTERP_KERNEL::Exception(oss.str().c_str());
1113 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1114 if(it==_groups.end())
1116 _groups[grpn].push_back(famn);
1120 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1121 if(it2==(*it).second.end())
1122 (*it).second.push_back(famn);
1127 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1128 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1129 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1131 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1133 std::string famNameCpp(famName);
1134 std::string otherCpp(otherFamName);
1135 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1137 std::vector<std::string>& v=(*it).second;
1138 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1140 v.push_back(otherCpp);
1145 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1147 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1150 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1152 std::string fam(familyNameToChange);
1153 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1155 std::vector<std::string>& fams((*it).second);
1156 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1160 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1166 * Returns a name of the family having a given id or, if no such a family exists, creates
1167 * a new uniquely named family and returns its name.
1168 * \param [in] id - the id of the family whose name is required.
1169 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1170 * \return std::string - the name of the existing or the created family.
1171 * \throw If it is not possible to create a unique family name.
1173 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1175 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1179 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1180 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1181 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1182 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1184 * This method will throws an exception if it is not possible to create a unique family name.
1186 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1188 std::vector<std::string> famAlreadyExisting(families.size());
1190 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1192 if((*it).second!=id)
1194 famAlreadyExisting[ii]=(*it).first;
1203 std::ostringstream oss; oss << "Family_" << id;
1204 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1210 * Sets names and ids of all families in \a this mesh.
1211 * \param [in] info - a map of a family name to a family id.
1213 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1219 * Sets names of all groups and families constituting them in \a this mesh.
1220 * \param [in] info - a map of a group name to a vector of names of families
1221 * constituting the group.
1223 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1229 * Returns an id of the family having a given name.
1230 * \param [in] name - the name of the family of interest.
1231 * \return int - the id of the family of interest.
1232 * \throw If no family with such a \a name exists.
1234 int MEDFileMesh::getFamilyId(const std::string& name) const
1236 std::string oname(name);
1237 std::map<std::string, int>::const_iterator it=_families.find(oname);
1238 std::vector<std::string> fams=getFamiliesNames();
1239 if(it==_families.end())
1241 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1242 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1243 throw INTERP_KERNEL::Exception(oss.str().c_str());
1245 return (*it).second;
1249 * Returns ids of the families having given names.
1250 * \param [in] fams - a sequence of the names of families of interest.
1251 * \return std::vector<int> - a sequence of the ids of families of interest.
1252 * \throw If \a fams contains a name of an inexistent family.
1254 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1256 std::vector<int> ret(fams.size());
1258 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1260 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1261 if(it2==_families.end())
1263 std::vector<std::string> fams2=getFamiliesNames();
1264 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1265 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1266 throw INTERP_KERNEL::Exception(oss.str().c_str());
1268 ret[i]=(*it2).second;
1274 * Returns a maximal abs(id) of families in \a this mesh.
1275 * \return int - the maximal norm of family id.
1276 * \throw If there are no families in \a this mesh.
1278 int MEDFileMesh::getMaxAbsFamilyId() const
1280 if(_families.empty())
1281 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1282 int ret=-std::numeric_limits<int>::max();
1283 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1285 ret=std::max(std::abs((*it).second),ret);
1291 * Returns a maximal id of families in \a this mesh.
1292 * \return int - the maximal family id.
1293 * \throw If there are no families in \a this mesh.
1295 int MEDFileMesh::getMaxFamilyId() const
1297 if(_families.empty())
1298 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1299 int ret=-std::numeric_limits<int>::max();
1300 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1302 ret=std::max((*it).second,ret);
1308 * Returns a minimal id of families in \a this mesh.
1309 * \return int - the minimal family id.
1310 * \throw If there are no families in \a this mesh.
1312 int MEDFileMesh::getMinFamilyId() const
1314 if(_families.empty())
1315 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1316 int ret=std::numeric_limits<int>::max();
1317 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1319 ret=std::min((*it).second,ret);
1325 * Returns a maximal id of families in \a this mesh. Not only named families are
1326 * considered but all family fields as well.
1327 * \return int - the maximal family id.
1329 int MEDFileMesh::getTheMaxAbsFamilyId() const
1331 int m1=-std::numeric_limits<int>::max();
1332 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1333 m1=std::max(std::abs((*it).second),m1);
1334 int m2=getMaxAbsFamilyIdInArrays();
1335 return std::max(m1,m2);
1339 * Returns a maximal id of families in \a this mesh. Not only named families are
1340 * considered but all family fields as well.
1341 * \return int - the maximal family id.
1343 int MEDFileMesh::getTheMaxFamilyId() const
1345 int m1=-std::numeric_limits<int>::max();
1346 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1347 m1=std::max((*it).second,m1);
1348 int m2=getMaxFamilyIdInArrays();
1349 return std::max(m1,m2);
1353 * Returns a minimal id of families in \a this mesh. Not only named families are
1354 * considered but all family fields as well.
1355 * \return int - the minimal family id.
1357 int MEDFileMesh::getTheMinFamilyId() const
1359 int m1=std::numeric_limits<int>::max();
1360 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1361 m1=std::min((*it).second,m1);
1362 int m2=getMinFamilyIdInArrays();
1363 return std::min(m1,m2);
1367 * This method only considers the maps. The contain of family array is ignored here.
1369 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1371 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1373 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1375 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1376 v.insert((*it).second);
1377 ret->alloc((int)v.size(),1);
1378 std::copy(v.begin(),v.end(),ret->getPointer());
1383 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1385 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1387 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1389 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1390 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1391 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1393 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1394 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1395 if((DataArrayInt *) ret)
1396 ret=dv->buildUnion(ret);
1404 * true is returned if no modification has been needed. false if family
1405 * renumbering has been needed.
1407 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1409 std::vector<int> levs=getNonEmptyLevelsExt();
1410 std::set<int> allFamIds;
1411 int maxId=getMaxFamilyId()+1;
1412 std::map<int,std::vector<int> > famIdsToRenum;
1413 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1415 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1418 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1420 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1422 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1424 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1427 if(famIdsToRenum.empty())
1429 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1430 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1432 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1433 int *famIdsToChange=fam->getPointer();
1434 std::map<int,int> ren;
1435 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1437 if(allIds->presenceOfValue(*it3))
1439 std::string famName=getFamilyNameGivenId(*it3);
1440 std::vector<std::string> grps=getGroupsOnFamily(famName);
1443 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1444 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1445 addFamilyOnGrp((*it4),newFam);
1448 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1449 for(const int *id=ids->begin();id!=ids->end();id++)
1450 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1456 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1457 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1458 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1459 * This method will throw an exception if a same family id is detected in different level.
1460 * \warning This policy is the opposite of those in MED file documentation ...
1462 void MEDFileMesh::normalizeFamIdsTrio()
1464 ensureDifferentFamIdsPerLevel();
1465 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1466 std::vector<int> levs=getNonEmptyLevelsExt();
1467 std::set<int> levsS(levs.begin(),levs.end());
1468 std::set<std::string> famsFetched;
1469 std::map<std::string,int> families;
1470 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1473 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1477 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1478 std::map<int,int> ren;
1479 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1481 int nbOfTuples=fam->getNumberOfTuples();
1482 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1483 for(int *w=start;w!=start+nbOfTuples;w++)
1485 for(const int *it=tmp->begin();it!=tmp->end();it++)
1487 if(allIds->presenceOfValue(*it))
1489 std::string famName=getFamilyNameGivenId(*it);
1490 families[famName]=ren[*it];
1491 famsFetched.insert(famName);
1496 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1499 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1503 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1504 std::map<int,int> ren;
1505 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1507 int nbOfTuples=fam->getNumberOfTuples();
1508 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1509 for(int *w=start;w!=start+nbOfTuples;w++)
1511 for(const int *it=tmp->begin();it!=tmp->end();it++)
1513 if(allIds->presenceOfValue(*it))
1515 std::string famName=getFamilyNameGivenId(*it);
1516 families[famName]=ren[*it];
1517 famsFetched.insert(famName);
1522 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1524 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1527 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1528 fam->fillWithZero();
1529 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1530 if(allIds->presenceOfValue(*it3))
1532 std::string famName=getFamilyNameGivenId(*it3);
1533 families[famName]=0;
1534 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 * This method normalizes fam id with the following policy.
1550 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1551 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1552 * This method will throw an exception if a same family id is detected in different level.
1554 void MEDFileMesh::normalizeFamIdsMEDFile()
1556 ensureDifferentFamIdsPerLevel();
1557 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1558 std::vector<int> levs=getNonEmptyLevelsExt();
1559 std::set<int> levsS(levs.begin(),levs.end());
1560 std::set<std::string> famsFetched;
1561 std::map<std::string,int> families;
1563 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1566 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1569 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1570 std::map<int,int> ren;
1571 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1573 int nbOfTuples=fam->getNumberOfTuples();
1574 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1575 for(int *w=start;w!=start+nbOfTuples;w++)
1577 for(const int *it=tmp->begin();it!=tmp->end();it++)
1579 if(allIds->presenceOfValue(*it))
1581 std::string famName=getFamilyNameGivenId(*it);
1582 families[famName]=ren[*it];
1583 famsFetched.insert(famName);
1589 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1591 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1594 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1595 std::map<int,int> ren;
1596 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1598 int nbOfTuples=fam->getNumberOfTuples();
1599 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1600 for(int *w=start;w!=start+nbOfTuples;w++)
1602 for(const int *it=tmp->begin();it!=tmp->end();it++)
1604 if(allIds->presenceOfValue(*it))
1606 std::string famName=getFamilyNameGivenId(*it);
1607 families[famName]=ren[*it];
1608 famsFetched.insert(famName);
1614 std::vector<std::string> allFams=getFamiliesNames();
1615 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1616 std::set<std::string> unFetchedIds;
1617 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1618 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1619 families[*it4]=_families[*it4];
1624 * Returns a name of the family by its id. If there are several families having the given
1625 * id, the name first in lexical order is returned.
1626 * \param [in] id - the id of the family whose name is required.
1627 * \return std::string - the name of the found family.
1628 * \throw If no family with the given \a id exists.
1630 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1632 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1633 if((*it).second==id)
1635 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1636 throw INTERP_KERNEL::Exception(oss.str().c_str());
1640 * Returns a string describing \a this mesh. This description includes the mesh name and
1641 * the mesh description string.
1642 * \return std::string - the mesh information string.
1644 std::string MEDFileMesh::simpleRepr() const
1646 std::ostringstream oss;
1647 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1648 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1649 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1654 * Returns ids of mesh entities contained in a given group of a given dimension.
1655 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1657 * \param [in] grp - the name of the group of interest.
1658 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1659 * returned instead of ids.
1660 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1661 * numbers, if available and required, of mesh entities of the group. The caller
1662 * is to delete this array using decrRef() as it is no more needed.
1663 * \throw If the name of a nonexistent group is specified.
1664 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1666 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1668 std::vector<std::string> tmp(1);
1670 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1676 * Returns ids of mesh entities contained in given groups of a given dimension.
1677 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1679 * \param [in] grps - the names of the groups of interest.
1680 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1681 * returned instead of ids.
1682 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1683 * numbers, if available and required, of mesh entities of the groups. The caller
1684 * is to delete this array using decrRef() as it is no more needed.
1685 * \throw If the name of a nonexistent group is present in \a grps.
1686 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1688 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1690 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1691 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1695 * Returns ids of mesh entities contained in a given family of a given dimension.
1696 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1698 * \param [in] fam - the name of the family of interest.
1699 * \param [in] renum - if \c true, the optional numbers of entities, 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 mesh entities of the family. 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 \a meshDimRelToMaxExt.
1706 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1708 std::vector<std::string> tmp(1);
1710 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1716 * Returns ids of nodes contained in a given group.
1717 * \param [in] grp - the name of the group of interest.
1718 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1719 * returned instead of ids.
1720 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1721 * numbers, if available and required, of nodes of the group. The caller
1722 * is to delete this array using decrRef() as it is no more needed.
1723 * \throw If the name of a nonexistent group is specified.
1724 * \throw If the family field is missing for nodes.
1726 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1728 std::vector<std::string> tmp(1);
1730 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1736 * Returns ids of nodes contained in given groups.
1737 * \param [in] grps - the names of the groups of interest.
1738 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1739 * returned instead of ids.
1740 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1741 * numbers, if available and required, of nodes of the groups. The caller
1742 * is to delete this array using decrRef() as it is no more needed.
1743 * \throw If the name of a nonexistent group is present in \a grps.
1744 * \throw If the family field is missing for nodes.
1746 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1748 return getGroupsArr(1,grps,renum);
1752 * Returns ids of nodes contained in a given group.
1753 * \param [in] grp - the name of the group of interest.
1754 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1755 * returned instead of ids.
1756 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1757 * numbers, if available and required, of nodes of the group. The caller
1758 * is to delete this array using decrRef() as it is no more needed.
1759 * \throw If the name of a nonexistent group is specified.
1760 * \throw If the family field is missing for nodes.
1762 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1764 std::vector<std::string> tmp(1);
1766 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1772 * Returns ids of nodes contained in given families.
1773 * \param [in] fams - the names of the families of interest.
1774 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1775 * returned instead of ids.
1776 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1777 * numbers, if available and required, of nodes of the families. The caller
1778 * is to delete this array using decrRef() as it is no more needed.
1779 * \throw If the family field is missing for nodes.
1781 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1783 return getFamiliesArr(1,fams,renum);
1787 * Adds groups of given dimension and creates corresponding families and family fields
1788 * given ids of mesh entities of each group.
1789 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1790 * \param [in] grps - a sequence of arrays of ids each describing a group.
1791 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1793 * \throw If names of some groups in \a grps are equal.
1794 * \throw If \a grps includes a group with an empty name.
1795 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1796 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1798 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1802 std::set<std::string> grpsName;
1803 std::vector<std::string> grpsName2(grps.size());
1806 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1808 grpsName.insert((*it)->getName());
1809 grpsName2[i]=(*it)->getName();
1811 if(grpsName.size()!=grps.size())
1812 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1813 if(grpsName.find(std::string(""))!=grpsName.end())
1814 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1815 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1816 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1817 std::vector< std::vector<int> > fidsOfGroups;
1820 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1824 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1825 for(unsigned int ii=0;ii<grps.size();ii++)
1827 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1828 grps2[ii]->setName(grps[ii]->getName());
1830 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1831 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1834 if(!_families.empty())
1835 offset=getMaxAbsFamilyId()+1;
1836 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1837 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1838 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1839 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1843 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1844 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1845 * For the moment, the two last input parameters are not taken into account.
1847 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1849 std::map<int,std::string> famInv;
1850 for(const int *it=famIds->begin();it!=famIds->end();it++)
1852 std::ostringstream oss;
1853 oss << "Family_" << (*it);
1854 _families[oss.str()]=(*it);
1855 famInv[*it]=oss.str();
1858 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1860 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1862 _groups[grpNames[i]].push_back(famInv[*it2]);
1867 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1869 std::vector<int> levs(getNonEmptyLevels());
1870 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1871 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1873 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1874 ret.insert(ret.end(),elts.begin(),elts.end());
1879 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1881 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1882 return mLev->getDistributionOfTypes();
1885 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1887 famArr->applyLin(offset>0?1:-1,offset,0);
1888 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1891 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1892 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1897 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1898 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1899 * If this method fails to find such a name it will throw an exception.
1901 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1904 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1907 std::size_t len=nameTry.length();
1908 for(std::size_t ii=1;ii<len;ii++)
1910 std::string tmp=nameTry.substr(ii,len-ii);
1911 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1917 for(std::size_t i=1;i<30;i++)
1919 std::string tmp1(nameTry.at(0),i);
1921 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1927 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1929 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1931 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1934 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
1936 std::size_t nbOfChunks=code.size()/3;
1937 if(code.size()%3!=0)
1938 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1940 for(std::size_t i=0;i<nbOfChunks;i++)
1949 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1950 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1951 * If _name is not empty and that 'm' has the same name nothing is done.
1952 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1954 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
1957 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1962 std::string name(m->getName());
1967 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1968 oss << name << "' ! Names must match !";
1969 throw INTERP_KERNEL::Exception(oss.str().c_str());
1973 if(_desc_name.empty())
1974 _desc_name=m->getDescription();
1977 std::string name(m->getDescription());
1980 if(_desc_name!=name)
1982 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1983 oss << name << "' ! Names must match !";
1984 throw INTERP_KERNEL::Exception(oss.str().c_str());
1990 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1992 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1993 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1995 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1996 oss << " - Groups lying on this family : ";
1997 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
1998 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1999 oss << std::endl << std::endl;
2004 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2005 * file. The mesh to load is specified by its name and numbers of a time step and an
2007 * \param [in] fileName - the name of MED file to read.
2008 * \param [in] mName - the name of the mesh to read.
2009 * \param [in] dt - the number of a time step.
2010 * \param [in] it - the number of an iteration.
2011 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2012 * mesh using decrRef() as it is no more needed.
2013 * \throw If the file is not readable.
2014 * \throw If there is no mesh with given attributes in the file.
2015 * \throw If the mesh in the file is not an unstructured one.
2017 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2019 MEDFileUtilities::CheckFileForRead(fileName);
2020 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2021 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2025 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2026 * file. The first mesh in the file is loaded.
2027 * \param [in] fileName - the name of MED file to read.
2028 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2029 * mesh using decrRef() as it is no more needed.
2030 * \throw If the file is not readable.
2031 * \throw If there is no meshes in the file.
2032 * \throw If the mesh in the file is not an unstructured one.
2034 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2036 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2039 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2040 throw INTERP_KERNEL::Exception(oss.str().c_str());
2042 MEDFileUtilities::CheckFileForRead(fileName);
2043 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2045 ParaMEDMEM::MEDCouplingMeshType meshType;
2047 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
2048 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2052 * Returns an empty instance of MEDFileUMesh.
2053 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2054 * mesh using decrRef() as it is no more needed.
2056 MEDFileUMesh *MEDFileUMesh::New()
2058 return new MEDFileUMesh;
2062 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2063 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2064 * \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.
2065 * 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
2066 * at most the memory consumtion.
2068 * \param [in] fileName - the name of the file.
2069 * \param [in] mName - the name of the mesh to be read.
2070 * \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.
2071 * \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.
2072 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2073 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2074 * \param [in] mrs - the request for what to be loaded.
2075 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2077 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)
2079 MEDFileUtilities::CheckFileForRead(fileName);
2080 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2081 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2085 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2086 * This method is \b NOT wrapped into python.
2088 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)
2090 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2091 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2095 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2097 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2098 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2102 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2104 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2105 ret.push_back((const DataArrayDouble*)_coords);
2106 ret.push_back((const DataArrayInt *)_fam_coords);
2107 ret.push_back((const DataArrayInt *)_num_coords);
2108 ret.push_back((const DataArrayInt *)_rev_num_coords);
2109 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2110 ret.push_back((const PartDefinition *)_part_coords);
2111 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2112 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2116 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2118 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2122 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2124 return new MEDFileUMesh;
2127 MEDFileMesh *MEDFileUMesh::deepCpy() const
2129 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2130 if((const DataArrayDouble*)_coords)
2131 ret->_coords=_coords->deepCpy();
2132 if((const DataArrayInt*)_fam_coords)
2133 ret->_fam_coords=_fam_coords->deepCpy();
2134 if((const DataArrayInt*)_num_coords)
2135 ret->_num_coords=_num_coords->deepCpy();
2136 if((const DataArrayInt*)_rev_num_coords)
2137 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2138 if((const DataArrayAsciiChar*)_name_coords)
2139 ret->_name_coords=_name_coords->deepCpy();
2141 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2143 if((const MEDFileUMeshSplitL1 *)(*it))
2144 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2146 if((const PartDefinition*)_part_coords)
2147 ret->_part_coords=_part_coords->deepCpy();
2152 * Checks if \a this and another mesh are equal.
2153 * \param [in] other - the mesh to compare with.
2154 * \param [in] eps - a precision used to compare real values.
2155 * \param [in,out] what - the string returning description of unequal data.
2156 * \return bool - \c true if the meshes are equal, \c false, else.
2158 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2160 if(!MEDFileMesh::isEqual(other,eps,what))
2162 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2165 what="Mesh types differ ! This is unstructured and other is NOT !";
2168 clearNonDiscrAttributes();
2169 otherC->clearNonDiscrAttributes();
2170 const DataArrayDouble *coo1=_coords;
2171 const DataArrayDouble *coo2=otherC->_coords;
2172 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2174 what="Mismatch of coordinates ! One is defined and not other !";
2179 bool ret=coo1->isEqual(*coo2,eps);
2182 what="Coords differ !";
2186 const DataArrayInt *famc1=_fam_coords;
2187 const DataArrayInt *famc2=otherC->_fam_coords;
2188 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2190 what="Mismatch of families arr on nodes ! One is defined and not other !";
2195 bool ret=famc1->isEqual(*famc2);
2198 what="Families arr on node differ !";
2202 const DataArrayInt *numc1=_num_coords;
2203 const DataArrayInt *numc2=otherC->_num_coords;
2204 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2206 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2211 bool ret=numc1->isEqual(*numc2);
2214 what="Numbering arr on node differ !";
2218 const DataArrayAsciiChar *namec1=_name_coords;
2219 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2220 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2222 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2227 bool ret=namec1->isEqual(*namec2);
2230 what="Names arr on node differ !";
2234 if(_ms.size()!=otherC->_ms.size())
2236 what="Number of levels differs !";
2239 std::size_t sz=_ms.size();
2240 for(std::size_t i=0;i<sz;i++)
2242 const MEDFileUMeshSplitL1 *s1=_ms[i];
2243 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2244 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2246 what="Mismatch of presence of sub levels !";
2251 bool ret=s1->isEqual(s2,eps,what);
2256 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2259 if((!pd0 && pd1) || (pd0 && !pd1))
2261 what=std::string("node part def is defined only for one among this or other !");
2264 return pd0->isEqual(pd1,what);
2268 * Clears redundant attributes of incorporated data arrays.
2270 void MEDFileUMesh::clearNonDiscrAttributes() const
2272 MEDFileMesh::clearNonDiscrAttributes();
2273 const DataArrayDouble *coo1=_coords;
2275 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2276 const DataArrayInt *famc1=_fam_coords;
2278 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2279 const DataArrayInt *numc1=_num_coords;
2281 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2282 const DataArrayAsciiChar *namc1=_name_coords;
2284 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2285 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2287 const MEDFileUMeshSplitL1 *tmp=(*it);
2289 tmp->clearNonDiscrAttributes();
2293 void MEDFileUMesh::setName(const std::string& name)
2295 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2296 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2297 (*it)->setName(name);
2298 MEDFileMesh::setName(name);
2301 MEDFileUMesh::MEDFileUMesh()
2305 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2308 loadUMeshFromFile(fid,mName,dt,it,mrs);
2310 catch(INTERP_KERNEL::Exception& e)
2316 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2317 * See MEDFileUMesh::LoadPartOf for detailed description.
2319 * \sa loadUMeshFromFile
2321 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)
2323 MEDFileUMeshL2 loaderl2;
2324 ParaMEDMEM::MEDCouplingMeshType meshType;
2327 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2328 if(meshType!=UNSTRUCTURED)
2330 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2331 throw INTERP_KERNEL::Exception(oss.str().c_str());
2333 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2334 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2338 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2340 * \sa loadPartUMeshFromFile
2342 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2344 MEDFileUMeshL2 loaderl2;
2345 ParaMEDMEM::MEDCouplingMeshType meshType;
2348 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2349 if(meshType!=UNSTRUCTURED)
2351 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2352 throw INTERP_KERNEL::Exception(oss.str().c_str());
2354 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2355 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2359 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2361 int lev=loaderl2.getNumberOfLevels();
2363 for(int i=0;i<lev;i++)
2365 if(!loaderl2.emptyLev(i))
2366 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2370 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2372 setName(loaderl2.getName());
2373 setDescription(loaderl2.getDescription());
2374 setUnivName(loaderl2.getUnivName());
2375 setIteration(loaderl2.getIteration());
2376 setOrder(loaderl2.getOrder());
2377 setTimeValue(loaderl2.getTime());
2378 setTimeUnit(loaderl2.getTimeUnit());
2379 _coords=loaderl2.getCoords();
2380 if(!mrs || mrs->isNodeFamilyFieldReading())
2381 _fam_coords=loaderl2.getCoordsFamily();
2382 if(!mrs || mrs->isNodeNumFieldReading())
2383 _num_coords=loaderl2.getCoordsNum();
2384 if(!mrs || mrs->isNodeNameFieldReading())
2385 _name_coords=loaderl2.getCoordsName();
2386 _part_coords=loaderl2.getPartDefOfCoo();
2390 MEDFileUMesh::~MEDFileUMesh()
2394 void MEDFileUMesh::writeLL(med_idt fid) const
2396 const DataArrayDouble *coo=_coords;
2397 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2398 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2399 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2400 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2401 int spaceDim=coo?coo->getNumberOfComponents():0;
2404 mdim=getMeshDimension();
2405 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2406 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2407 for(int i=0;i<spaceDim;i++)
2409 std::string info=coo->getInfoOnComponent(i);
2411 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2412 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
2413 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
2415 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2416 MEDmeshUniversalNameWr(fid,maa);
2417 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2418 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2419 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2420 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2421 (*it)->write(fid,meshName,mdim);
2422 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2426 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2427 * \return std::vector<int> - a sequence of the relative dimensions.
2429 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2431 std::vector<int> ret;
2433 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2434 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2441 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2442 * \return std::vector<int> - a sequence of the relative dimensions.
2444 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2446 std::vector<int> ret0=getNonEmptyLevels();
2447 if((const DataArrayDouble *) _coords)
2449 std::vector<int> ret(ret0.size()+1);
2451 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2457 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2459 std::vector<int> ret;
2460 const DataArrayInt *famCoo(_fam_coords);
2464 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2466 const MEDFileUMeshSplitL1 *cur(*it);
2468 if(cur->getFamilyField())
2474 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2476 std::vector<int> ret;
2477 const DataArrayInt *numCoo(_num_coords);
2481 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2483 const MEDFileUMeshSplitL1 *cur(*it);
2485 if(cur->getNumberField())
2491 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2493 std::vector<int> ret;
2494 const DataArrayAsciiChar *nameCoo(_name_coords);
2498 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2500 const MEDFileUMeshSplitL1 *cur(*it);
2502 if(cur->getNameField())
2509 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2510 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2511 * \param [in] grp - the name of the group of interest.
2512 * \return std::vector<int> - a sequence of the relative dimensions.
2514 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2516 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2517 return getFamsNonEmptyLevels(fams);
2521 * Returns all relative mesh levels (including nodes) where a given group is defined.
2522 * \param [in] grp - the name of the group of interest.
2523 * \return std::vector<int> - a sequence of the relative dimensions.
2525 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2527 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2528 return getFamsNonEmptyLevelsExt(fams);
2532 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2533 * To include nodes, call getFamNonEmptyLevelsExt() method.
2534 * \param [in] fam - the name of the family of interest.
2535 * \return std::vector<int> - a sequence of the relative dimensions.
2537 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2539 std::vector<std::string> fams(1,std::string(fam));
2540 return getFamsNonEmptyLevels(fams);
2544 * Returns all relative mesh levels (including nodes) where a given family is defined.
2545 * \param [in] fam - the name of the family of interest.
2546 * \return std::vector<int> - a sequence of the relative dimensions.
2548 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2550 std::vector<std::string> fams(1,std::string(fam));
2551 return getFamsNonEmptyLevelsExt(fams);
2555 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2556 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2557 * \param [in] grps - a sequence of names of the groups of interest.
2558 * \return std::vector<int> - a sequence of the relative dimensions.
2560 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2562 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2563 return getFamsNonEmptyLevels(fams);
2567 * Returns all relative mesh levels (including nodes) where given groups are defined.
2568 * \param [in] grps - a sequence of names of the groups of interest.
2569 * \return std::vector<int> - a sequence of the relative dimensions.
2571 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2573 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2574 return getFamsNonEmptyLevelsExt(fams);
2578 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2579 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2580 * \param [in] fams - the name of the family of interest.
2581 * \return std::vector<int> - a sequence of the relative dimensions.
2583 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2585 std::vector<int> ret;
2586 std::vector<int> levs=getNonEmptyLevels();
2587 std::vector<int> famIds=getFamiliesIds(fams);
2588 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2589 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2595 * Returns all relative mesh levels (including nodes) where given families are defined.
2596 * \param [in] fams - the names of the families of interest.
2597 * \return std::vector<int> - a sequence of the relative dimensions.
2599 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2601 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2602 const DataArrayInt *famCoords=_fam_coords;
2605 std::vector<int> famIds=getFamiliesIds(fams);
2606 if(famCoords->presenceOfValue(famIds))
2608 std::vector<int> ret(ret0.size()+1);
2610 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2618 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2619 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2620 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2623 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2625 std::vector<std::string> ret;
2626 std::vector<std::string> allGrps=getGroupsNames();
2627 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2629 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2630 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2636 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2638 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2639 if((const DataArrayInt *)_fam_coords)
2641 int val=_fam_coords->getMaxValue(tmp);
2642 ret=std::max(ret,std::abs(val));
2644 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2646 if((const MEDFileUMeshSplitL1 *)(*it))
2648 const DataArrayInt *da=(*it)->getFamilyField();
2651 int val=da->getMaxValue(tmp);
2652 ret=std::max(ret,std::abs(val));
2659 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2661 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2662 if((const DataArrayInt *)_fam_coords)
2664 int val=_fam_coords->getMaxValue(tmp);
2665 ret=std::max(ret,val);
2667 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2669 if((const MEDFileUMeshSplitL1 *)(*it))
2671 const DataArrayInt *da=(*it)->getFamilyField();
2674 int val=da->getMaxValue(tmp);
2675 ret=std::max(ret,val);
2682 int MEDFileUMesh::getMinFamilyIdInArrays() const
2684 int ret=std::numeric_limits<int>::max(),tmp=-1;
2685 if((const DataArrayInt *)_fam_coords)
2687 int val=_fam_coords->getMinValue(tmp);
2688 ret=std::min(ret,val);
2690 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2692 if((const MEDFileUMeshSplitL1 *)(*it))
2694 const DataArrayInt *da=(*it)->getFamilyField();
2697 int val=da->getMinValue(tmp);
2698 ret=std::min(ret,val);
2706 * Returns the dimension on cells in \a this mesh.
2707 * \return int - the mesh dimension.
2708 * \throw If there are no cells in this mesh.
2710 int MEDFileUMesh::getMeshDimension() const
2713 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2714 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2715 return (*it)->getMeshDimension()+lev;
2716 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2720 * Returns the space dimension of \a this mesh that is equal to number of components in
2721 * the node coordinates array.
2722 * \return int - the space dimension of \a this mesh.
2723 * \throw If the node coordinates array is not available.
2725 int MEDFileUMesh::getSpaceDimension() const
2727 const DataArrayDouble *coo=_coords;
2729 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2730 return coo->getNumberOfComponents();
2734 * Returns a string describing \a this mesh.
2735 * \return std::string - the mesh information string.
2737 std::string MEDFileUMesh::simpleRepr() const
2739 std::ostringstream oss;
2740 oss << MEDFileMesh::simpleRepr();
2741 const DataArrayDouble *coo=_coords;
2742 oss << "- The dimension of the space is ";
2743 static const char MSG1[]= "*** NO COORDS SET ***";
2744 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2746 oss << _coords->getNumberOfComponents() << std::endl;
2748 oss << MSG1 << std::endl;
2749 oss << "- Type of the mesh : UNSTRUCTURED\n";
2750 oss << "- Number of nodes : ";
2752 oss << _coords->getNumberOfTuples() << std::endl;
2754 oss << MSG1 << std::endl;
2755 std::size_t nbOfLev=_ms.size();
2756 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2757 for(std::size_t i=0;i<nbOfLev;i++)
2759 const MEDFileUMeshSplitL1 *lev=_ms[i];
2760 oss << " - Level #" << -((int) i) << " has dimension : ";
2763 oss << lev->getMeshDimension() << std::endl;
2764 lev->simpleRepr(oss);
2767 oss << MSG2 << std::endl;
2769 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2772 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2773 oss << "- Names of coordinates :" << std::endl;
2774 std::vector<std::string> vars=coo->getVarsOnComponent();
2775 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2776 oss << std::endl << "- Units of coordinates : " << std::endl;
2777 std::vector<std::string> units=coo->getUnitsOnComponent();
2778 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2780 oss << std::endl << std::endl;
2786 * Returns a full textual description of \a this mesh.
2787 * \return std::string - the string holding the mesh description.
2789 std::string MEDFileUMesh::advancedRepr() const
2791 return simpleRepr();
2795 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2796 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2797 * \return int - the number of entities.
2798 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2800 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2802 if(meshDimRelToMaxExt==1)
2804 if(!((const DataArrayDouble *)_coords))
2805 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2806 return _coords->getNumberOfTuples();
2808 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2812 * Returns the family field for mesh entities of a given dimension.
2813 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2814 * \return const DataArrayInt * - the family field. It is an array of ids of families
2815 * each mesh entity belongs to. It can be \c NULL.
2817 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2819 if(meshDimRelToMaxExt==1)
2821 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2822 return l1->getFamilyField();
2826 * Returns the optional numbers of mesh entities of a given dimension.
2827 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2828 * \return const DataArrayInt * - the array of the entity numbers.
2829 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2831 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2833 if(meshDimRelToMaxExt==1)
2835 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2836 return l1->getNumberField();
2839 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2841 if(meshDimRelToMaxExt==1)
2842 return _name_coords;
2843 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2844 return l1->getNameField();
2848 * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file).
2850 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
2851 * \param [in] gt - The input geometric type for which the part definition is requested.
2852 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
2854 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
2856 if(meshDimRelToMaxExt==1)
2857 return _part_coords;
2858 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2859 return l1->getPartDef(gt);
2862 int MEDFileUMesh::getNumberOfNodes() const
2864 const DataArrayDouble *coo=_coords;
2866 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2867 return coo->getNumberOfTuples();
2870 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
2872 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2873 return l1->getNumberOfCells();
2876 bool MEDFileUMesh::hasImplicitPart() const
2881 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
2883 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
2886 void MEDFileUMesh::releaseImplicitPartIfAny() const
2890 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2892 std::size_t sz(st.getNumberOfItems());
2893 for(std::size_t i=0;i<sz;i++)
2895 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2896 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2897 if(st[i].getPflName().empty())
2898 m->computeNodeIdsAlg(nodesFetched);
2901 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2902 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2903 m2->computeNodeIdsAlg(nodesFetched);
2909 * Returns the optional numbers of mesh entities of a given dimension transformed using
2910 * DataArrayInt::invertArrayN2O2O2N().
2911 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2912 * \return const DataArrayInt * - the array of the entity numbers transformed using
2913 * DataArrayInt::invertArrayN2O2O2N().
2914 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2916 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2918 if(meshDimRelToMaxExt==1)
2920 if(!((const DataArrayInt *)_num_coords))
2921 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2922 return _rev_num_coords;
2924 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2925 return l1->getRevNumberField();
2929 * Returns a pointer to the node coordinates array of \a this mesh \b without
2930 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2932 DataArrayDouble *MEDFileUMesh::getCoords() const
2934 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2935 if((DataArrayDouble *)tmp)
2943 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2944 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2946 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2947 * \param [in] grp - the name of the group whose mesh entities are included in the
2949 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2950 * according to the optional numbers of entities, if available.
2951 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2952 * delete this mesh using decrRef() as it is no more needed.
2953 * \throw If the name of a nonexistent group is specified.
2954 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2956 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2958 synchronizeTinyInfoOnLeaves();
2959 std::vector<std::string> tmp(1);
2961 return getGroups(meshDimRelToMaxExt,tmp,renum);
2965 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2966 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2968 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2969 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2971 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2972 * according to the optional numbers of entities, if available.
2973 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2974 * delete this mesh using decrRef() as it is no more needed.
2975 * \throw If a name of a nonexistent group is present in \a grps.
2976 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2978 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2980 synchronizeTinyInfoOnLeaves();
2981 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2982 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2983 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2984 zeRet->setName(grps[0]);
2985 return zeRet.retn();
2989 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2990 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2992 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2993 * \param [in] fam - the name of the family whose mesh entities are included in the
2995 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2996 * according to the optional numbers of entities, if available.
2997 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2998 * delete this mesh using decrRef() as it is no more needed.
2999 * \throw If a name of a nonexistent family is present in \a grps.
3000 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3002 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3004 synchronizeTinyInfoOnLeaves();
3005 std::vector<std::string> tmp(1);
3007 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3011 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3012 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3014 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3015 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3017 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3018 * according to the optional numbers of entities, if available.
3019 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3020 * delete this mesh using decrRef() as it is no more needed.
3021 * \throw If a name of a nonexistent family is present in \a fams.
3022 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3024 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3026 synchronizeTinyInfoOnLeaves();
3027 if(meshDimRelToMaxExt==1)
3029 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3030 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3031 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3035 std::vector<int> famIds=getFamiliesIds(fams);
3036 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3037 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3039 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3041 zeRet=l1->getFamilyPart(0,0,renum);
3042 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3043 zeRet->setName(fams[0]);
3044 return zeRet.retn();
3048 * Returns ids of mesh entities contained in given families of a given dimension.
3049 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3051 * \param [in] fams - the names of the families of interest.
3052 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3053 * returned instead of ids.
3054 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3055 * numbers, if available and required, of mesh entities of the families. The caller
3056 * is to delete this array using decrRef() as it is no more needed.
3057 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3059 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3061 std::vector<int> famIds=getFamiliesIds(fams);
3062 if(meshDimRelToMaxExt==1)
3064 if((const DataArrayInt *)_fam_coords)
3066 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3068 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3070 da=_fam_coords->getIdsEqualList(0,0);
3072 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3077 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3079 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3081 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3083 return l1->getFamilyPartArr(0,0,renum);
3087 * Returns a MEDCouplingUMesh of a given relative dimension.
3088 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3089 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3090 * To build a valid MEDCouplingUMesh from the returned one in this case,
3091 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3092 * \param [in] meshDimRelToMax - the relative dimension of interest.
3093 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3094 * optional numbers of mesh entities.
3095 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3096 * delete using decrRef() as it is no more needed.
3097 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3098 * \sa getGenMeshAtLevel()
3100 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3102 synchronizeTinyInfoOnLeaves();
3103 if(meshDimRelToMaxExt==1)
3107 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3108 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3109 umesh->setCoords(cc);
3110 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3111 umesh->setName(getName());
3115 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3116 return l1->getWholeMesh(renum);
3120 * Returns a MEDCouplingUMesh of a given relative dimension.
3121 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3122 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3123 * To build a valid MEDCouplingUMesh from the returned one in this case,
3124 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3125 * \param [in] meshDimRelToMax - the relative dimension of interest.
3126 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3127 * optional numbers of mesh entities.
3128 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3129 * delete using decrRef() as it is no more needed.
3130 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3131 * \sa getMeshAtLevel()
3133 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3135 return getMeshAtLevel(meshDimRelToMax,renum);
3138 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3140 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3141 return l1->getDistributionOfTypes();
3145 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3146 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3147 * optional numbers of mesh entities.
3148 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3149 * delete using decrRef() as it is no more needed.
3150 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3152 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3154 return getMeshAtLevel(0,renum);
3158 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3159 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3160 * optional numbers of mesh entities.
3161 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3162 * delete using decrRef() as it is no more needed.
3163 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3165 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3167 return getMeshAtLevel(-1,renum);
3171 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3172 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3173 * optional numbers of mesh entities.
3174 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3175 * delete using decrRef() as it is no more needed.
3176 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3178 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3180 return getMeshAtLevel(-2,renum);
3184 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3185 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3186 * optional numbers of mesh entities.
3187 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3188 * delete using decrRef() as it is no more needed.
3189 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3191 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3193 return getMeshAtLevel(-3,renum);
3197 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3198 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3199 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3200 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3202 void MEDFileUMesh::forceComputationOfParts() const
3204 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3206 const MEDFileUMeshSplitL1 *elt(*it);
3208 elt->forceComputationOfParts();
3213 * This method returns a vector of mesh parts containing each exactly one geometric type.
3214 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3215 * This method is only for memory aware users.
3216 * The returned pointers are **NOT** new object pointer. No need to mange them.
3218 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3220 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3221 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3225 * This method returns the part of \a this having the geometric type \a gt.
3226 * If such part is not existing an exception will be thrown.
3227 * The returned pointer is **NOT** new object pointer. No need to mange it.
3229 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3231 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3232 int lev=(int)cm.getDimension()-getMeshDimension();
3233 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3234 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3238 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3239 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3241 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3243 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3244 return sp->getGeoTypes();
3248 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3249 * \param [in] gt - the geometric type for which the family field is asked.
3250 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3251 * delete using decrRef() as it is no more needed.
3252 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3254 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3256 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3257 int lev=(int)cm.getDimension()-getMeshDimension();
3258 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3259 return sp->extractFamilyFieldOnGeoType(gt);
3263 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3264 * \param [in] gt - the geometric type for which the number field is asked.
3265 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3266 * delete using decrRef() as it is no more needed.
3267 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3269 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3271 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3272 int lev=(int)cm.getDimension()-getMeshDimension();
3273 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3274 return sp->extractNumberFieldOnGeoType(gt);
3278 * This method returns for specified geometric type \a gt the relative level to \a this.
3279 * If the relative level is empty an exception will be thrown.
3281 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3283 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3284 int ret((int)cm.getDimension()-getMeshDimension());
3285 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3289 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3291 if(meshDimRelToMaxExt==1)
3292 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3293 if(meshDimRelToMaxExt>1)
3294 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3295 int tracucedRk=-meshDimRelToMaxExt;
3296 if(tracucedRk>=(int)_ms.size())
3297 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3298 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3299 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3300 return _ms[tracucedRk];
3303 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3305 if(meshDimRelToMaxExt==1)
3306 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3307 if(meshDimRelToMaxExt>1)
3308 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3309 int tracucedRk=-meshDimRelToMaxExt;
3310 if(tracucedRk>=(int)_ms.size())
3311 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3312 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3313 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3314 return _ms[tracucedRk];
3317 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3319 if(-meshDimRelToMax>=(int)_ms.size())
3320 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3322 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3324 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3326 int ref=(*it)->getMeshDimension();
3327 if(ref+i!=meshDim-meshDimRelToMax)
3328 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3334 * Sets the node coordinates array of \a this mesh.
3335 * \param [in] coords - the new node coordinates array.
3336 * \throw If \a coords == \c NULL.
3338 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3341 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3342 coords->checkAllocated();
3343 int nbOfTuples=coords->getNumberOfTuples();
3346 _fam_coords=DataArrayInt::New();
3347 _fam_coords->alloc(nbOfTuples,1);
3348 _fam_coords->fillWithZero();
3349 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3350 if((MEDFileUMeshSplitL1 *)(*it))
3351 (*it)->setCoords(coords);
3355 * Removes all groups of a given dimension in \a this mesh.
3356 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3357 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3359 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3361 if(meshDimRelToMaxExt==1)
3363 if((DataArrayInt *)_fam_coords)
3364 _fam_coords->fillWithZero();
3367 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3368 l1->eraseFamilyField();
3373 * Removes all families with ids not present in the family fields of \a this mesh.
3375 void MEDFileUMesh::optimizeFamilies()
3377 std::vector<int> levs=getNonEmptyLevelsExt();
3378 std::set<int> allFamsIds;
3379 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3381 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3382 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3384 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3387 std::set<std::string> famNamesToKill;
3388 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3390 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3391 famNamesToKill.insert((*it).first);
3393 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3394 _families.erase(*it);
3395 std::vector<std::string> grpNamesToKill;
3396 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3398 std::vector<std::string> tmp;
3399 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3401 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3402 tmp.push_back(*it2);
3407 tmp.push_back((*it).first);
3409 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3413 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3415 std::vector<int> levs=getNonEmptyLevels();
3416 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3417 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3418 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3419 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3420 int nbNodes=m0->getNumberOfNodes();
3421 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3422 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3423 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3424 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3425 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3426 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3427 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3428 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3429 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3430 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3431 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3432 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3433 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3434 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3435 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3436 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3437 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3438 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3439 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3440 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3441 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3442 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3443 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3444 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3445 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3446 m0->setCoords(tmp0->getCoords());
3447 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3448 m1->setCoords(m0->getCoords());
3449 _coords=m0->getCoords(); _coords->incrRef();
3450 // duplication of cells in group 'grpNameM1' on level -1
3451 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3452 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3453 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3454 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3455 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3457 newm1->setName(getName());
3458 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3460 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3461 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3462 newFam->alloc(newm1->getNumberOfCells(),1);
3463 int idd=getMaxFamilyId()+1;
3464 int globStart=0,start=0,end,globEnd;
3465 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3466 for(int i=0;i<nbOfChunks;i++)
3468 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3469 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3471 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3472 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3473 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3478 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3482 newm1->setCoords(getCoords());
3483 setMeshAtLevel(-1,newm1);
3484 setFamilyFieldArr(-1,newFam);
3485 std::string grpName2(grpNameM1); grpName2+="_dup";
3486 addFamily(grpName2,idd);
3487 addFamilyOnGrp(grpName2,grpName2);
3492 int newNbOfNodes=getCoords()->getNumberOfTuples();
3493 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3494 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3495 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3498 nodesDuplicated=nodeIdsToDuplicate.retn();
3499 cellsModified=cellsToModifyConn0.retn();
3500 cellsNotModified=cellsToModifyConn1.retn();
3504 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3505 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3506 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3508 * \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.
3509 * 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.
3511 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3513 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3514 std::vector<int> levs=getNonEmptyLevels();
3516 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3517 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3520 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3522 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3523 std::vector<int> code1=m->getDistributionOfTypes();
3524 end=PutInThirdComponentOfCodeOffset(code1,start);
3525 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3526 bool hasChanged=m->unPolyze();
3527 DataArrayInt *fake=0;
3528 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3529 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3531 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3534 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3535 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3537 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3538 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3539 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3540 setMeshAtLevel(*it,m);
3541 std::vector<int> code2=m->getDistributionOfTypes();
3542 end=PutInThirdComponentOfCodeOffset(code2,start);
3543 newCode.insert(newCode.end(),code2.begin(),code2.end());
3545 if(o2nCellsPart2->isIdentity())
3549 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3550 setFamilyFieldArr(*it,newFamField);
3554 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3555 setRenumFieldArr(*it,newNumField);
3560 newCode.insert(newCode.end(),code1.begin(),code1.end());
3566 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3567 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3568 o2nRenumCell=o2nRenumCellRet.retn();
3573 struct MEDLoaderAccVisit1
3575 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3576 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3577 int _new_nb_of_nodes;
3581 * 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.
3582 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3583 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3584 * -1 values in returned array means that the corresponding old node is no more used.
3586 * \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
3587 * is modified in \a this.
3588 * \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
3591 DataArrayInt *MEDFileUMesh::zipCoords()
3593 const DataArrayDouble *coo(getCoords());
3595 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3596 int nbOfNodes(coo->getNumberOfTuples());
3597 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3598 std::vector<int> neLevs(getNonEmptyLevels());
3599 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3601 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3602 if(zeLev->isMeshStoredSplitByType())
3604 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3605 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3607 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3611 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3612 mesh->computeNodeIdsAlg(nodeIdsInUse);
3615 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3616 if(nbrOfNodesInUse==nbOfNodes)
3617 return 0;//no need to update _part_coords
3618 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3619 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3620 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3621 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3622 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3623 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3624 if((const DataArrayInt *)_fam_coords)
3625 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3626 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3627 if((const DataArrayInt *)_num_coords)
3628 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3629 if((const DataArrayAsciiChar *)_name_coords)
3630 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3631 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3632 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3634 if((MEDFileUMeshSplitL1*)*it)
3636 (*it)->renumberNodesInConn(ret->begin());
3637 (*it)->setCoords(_coords);
3640 // updates _part_coords
3641 const PartDefinition *pc(_part_coords);
3644 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3645 _part_coords=tmpPD->composeWith(pc);
3651 * This method performs an extrusion along a path defined by \a m1D.
3652 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3653 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3654 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3655 * This method scans all levels in \a this
3656 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3658 * \param [in] m1D - the mesh defining the extrusion path.
3659 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3660 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3662 * \sa MEDCouplingUMesh::buildExtrudedMesh
3664 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3666 if(getMeshDimension()!=2)
3667 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3668 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3669 m1D->checkCoherency();
3670 if(m1D->getMeshDimension()!=1)
3671 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3672 int nbRep(m1D->getNumberOfCells());
3673 std::vector<int> levs(getNonEmptyLevels());
3674 std::vector<std::string> grps(getGroupsNames());
3675 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3676 DataArrayDouble *coords(0);
3677 std::size_t nbOfLevsOut(levs.size()+1);
3678 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3679 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3681 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3682 item=item->clone(false);
3683 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3684 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3685 tmp->changeSpaceDimension(3+(*lev),0.);
3686 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3687 zeList.push_back(elt);
3689 coords=elt->getCoords();
3692 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3693 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3695 (*it)->setName(getName());
3696 (*it)->setCoords(coords);
3698 for(std::size_t ii=0;ii!=zeList.size();ii++)
3701 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
3704 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
3705 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
3706 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
3707 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
3708 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
3709 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
3710 std::vector<const MEDCouplingUMesh *> elts(3);
3711 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
3712 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
3713 elt->setName(getName());
3716 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
3717 ret->setMeshAtLevel(lev,elt);
3719 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
3720 endLev=endLev->clone(false); endLev->setCoords(coords);
3721 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
3722 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
3723 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
3724 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
3725 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
3726 endLev->setName(getName());
3727 ret->setMeshAtLevel(levs.back()-1,endLev);
3729 for(std::size_t ii=0;ii!=zeList.size();ii++)
3732 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3733 std::vector< const DataArrayInt * > outGrps2;
3736 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3738 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
3739 if(!grpArr->empty())
3741 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
3742 int offset0(zeList[ii]->getNumberOfCells());
3743 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
3744 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
3745 std::ostringstream oss; oss << grpArr2->getName() << "_top";
3746 grpArr2->setName(oss.str());
3747 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3748 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3749 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3750 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3755 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3757 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
3758 if(!grpArr->empty())
3760 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
3761 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
3762 std::vector< const DataArrayInt *> grpArrs2(nbRep);
3763 for(int iii=0;iii<nbRep;iii++)
3765 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
3766 grpArrs2[iii]=grpArrs[iii];
3768 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
3769 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3770 std::ostringstream grpName; grpName << *grp << "_extruded";
3771 grpArrExt->setName(grpName.str());
3772 outGrps.push_back(grpArrExt);
3773 outGrps2.push_back(grpArrExt);
3776 ret->setGroupsAtLevel(lev,outGrps2);
3778 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3779 std::vector< const DataArrayInt * > outGrps2;
3780 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3782 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
3783 if(grpArr1->empty())
3785 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
3786 std::ostringstream grpName; grpName << *grp << "_top";
3787 grpArr2->setName(grpName.str());
3788 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
3789 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3790 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3792 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
3796 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
3798 clearNonDiscrAttributes();
3799 forceComputationOfParts();
3800 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
3801 std::vector<int> layer0;
3802 layer0.push_back(_order); //0 i
3803 layer0.push_back(_iteration);//1 i
3804 layer0.push_back(getSpaceDimension());//2 i
3805 tinyDouble.push_back(_time);//0 d
3806 tinyStr.push_back(_name);//0 s
3807 tinyStr.push_back(_desc_name);//1 s
3808 for(int i=0;i<getSpaceDimension();i++)
3809 tinyStr.push_back(_coords->getInfoOnComponent(i));
3810 layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
3811 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3813 tinyStr.push_back((*it).first);
3814 layer0.push_back((*it).second);
3816 layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
3817 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
3819 layer0.push_back((int)(*it0).second.size());
3820 tinyStr.push_back((*it0).first);
3821 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
3822 tinyStr.push_back(*it1);
3824 // sizeof(layer0)==3+aa+1+bb layer#0
3825 bigArrayD=_coords;// 0 bd
3826 bigArraysI.push_back(_fam_coords);// 0 bi
3827 bigArraysI.push_back(_num_coords);// 1 bi
3828 const PartDefinition *pd(_part_coords);
3830 layer0.push_back(-1);
3833 std::vector<int> tmp0;
3834 pd->serialize(tmp0,bigArraysI);
3835 tinyInt.push_back(tmp0.size());
3836 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
3839 std::vector<int> layer1;
3840 std::vector<int> levs(getNonEmptyLevels());
3841 layer1.push_back((int)levs.size());// 0 i <- key
3842 layer1.insert(layer1.end(),levs.begin(),levs.end());
3843 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3845 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
3846 lev->serialize(layer1,bigArraysI);
3848 // put layers all together.
3849 tinyInt.push_back(layer0.size());
3850 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
3851 tinyInt.push_back(layer1.size());
3852 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
3855 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
3856 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
3858 int sz0(tinyInt[0]);
3859 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
3860 int sz1(tinyInt[sz0+1]);
3861 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
3863 std::reverse(layer0.begin(),layer0.end());
3864 std::reverse(layer1.begin(),layer1.end());
3865 std::reverse(tinyDouble.begin(),tinyDouble.end());
3866 std::reverse(tinyStr.begin(),tinyStr.end());
3867 std::reverse(bigArraysI.begin(),bigArraysI.end());
3869 _order=layer0.back(); layer0.pop_back();
3870 _iteration=layer0.back(); layer0.pop_back();
3871 int spaceDim(layer0.back()); layer0.pop_back();
3872 _time=tinyDouble.back(); tinyDouble.pop_back();
3873 _name=tinyStr.back(); tinyStr.pop_back();
3874 _desc_name=tinyStr.back(); tinyStr.pop_back();
3875 _coords=bigArrayD; _coords->rearrange(spaceDim);
3876 for(int i=0;i<spaceDim;i++)
3878 _coords->setInfoOnComponent(i,tinyStr.back());
3881 int nbOfFams(layer0.back()); layer0.pop_back();
3883 for(int i=0;i<nbOfFams;i++)
3885 _families[tinyStr.back()]=layer0.back();
3886 tinyStr.pop_back(); layer0.pop_back();
3888 int nbGroups(layer0.back()); layer0.pop_back();
3890 for(int i=0;i<nbGroups;i++)
3892 std::string grpName(tinyStr.back()); tinyStr.pop_back();
3893 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
3894 std::vector<std::string> fams(nbOfFamsOnGrp);
3895 for(int j=0;j<nbOfFamsOnGrp;j++)
3897 fams[j]=tinyStr.back(); tinyStr.pop_back();
3899 _groups[grpName]=fams;
3901 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
3902 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
3904 int isPd(layer0.back()); layer0.pop_back();
3907 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
3908 layer0.erase(layer0.begin(),layer0.begin()+isPd);
3909 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
3912 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
3914 int nbLevs(layer1.back()); layer1.pop_back();
3915 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
3917 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
3918 _ms.resize(maxLev+1);
3919 for(int i=0;i<nbLevs;i++)
3923 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
3928 * Adds a group of nodes to \a this mesh.
3929 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3930 * The ids should be sorted and different each other (MED file norm).
3932 * \warning this method can alter default "FAMILLE_ZERO" family.
3933 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
3935 * \throw If the node coordinates array is not set.
3936 * \throw If \a ids == \c NULL.
3937 * \throw If \a ids->getName() == "".
3938 * \throw If \a ids does not respect the MED file norm.
3939 * \throw If a group with name \a ids->getName() already exists.
3941 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
3943 const DataArrayDouble *coords=_coords;
3945 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3946 int nbOfNodes=coords->getNumberOfTuples();
3947 if(!((DataArrayInt *)_fam_coords))
3948 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3950 addGroupUnderground(true,ids,_fam_coords);
3954 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3956 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3957 * The ids should be sorted and different each other (MED file norm).
3959 * \warning this method can alter default "FAMILLE_ZERO" family.
3960 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
3962 * \throw If the node coordinates array is not set.
3963 * \throw If \a ids == \c NULL.
3964 * \throw If \a ids->getName() == "".
3965 * \throw If \a ids does not respect the MED file norm.
3966 * \throw If a group with name \a ids->getName() already exists.
3968 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
3970 std::vector<int> levs=getNonEmptyLevelsExt();
3971 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3973 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3974 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3976 if(meshDimRelToMaxExt==1)
3977 { addNodeGroup(ids); return ; }
3978 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3979 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3980 addGroupUnderground(false,ids,fam);
3984 * \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).
3985 * \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)
3987 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
3990 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3991 std::string grpName(ids->getName());
3993 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3994 ids->checkStrictlyMonotonic(true);
3995 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3996 std::vector<std::string> grpsNames=getGroupsNames();
3997 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3999 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
4000 throw INTERP_KERNEL::Exception(oss.str().c_str());
4002 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
4003 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
4004 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
4005 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
4006 std::vector<int> familyIds;
4007 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
4008 int maxVal=getTheMaxAbsFamilyId()+1;
4009 std::map<std::string,int> families(_families);
4010 std::map<std::string, std::vector<std::string> > groups(_groups);
4011 std::vector<std::string> fams;
4012 bool created(false);
4013 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
4015 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
4016 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
4017 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
4018 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
4021 bool isFamPresent=false;
4022 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
4023 isFamPresent=(*itl)->presenceOfValue(*famId);
4025 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
4028 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
4029 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
4030 fams.push_back(locFamName);
4031 if(existsFamily(*famId))
4033 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
4034 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
4037 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
4041 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
4042 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
4043 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
4044 if(existsFamily(*famId))
4046 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
4047 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
4052 for(std::size_t i=0;i<familyIds.size();i++)
4054 DataArrayInt *da=idsPerfamiliyIds[i];
4055 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
4059 _groups[grpName]=fams;
4063 * Changes a name of a family specified by its id.
4064 * \param [in] id - the id of the family of interest.
4065 * \param [in] newFamName - the new family name.
4066 * \throw If no family with the given \a id exists.
4068 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4070 std::string oldName=getFamilyNameGivenId(id);
4071 _families.erase(oldName);
4072 _families[newFamName]=id;
4076 * Removes a mesh of a given dimension.
4077 * \param [in] meshDimRelToMax - the relative dimension of interest.
4078 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4080 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4082 std::vector<int> levSet=getNonEmptyLevels();
4083 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4084 if(it==levSet.end())
4085 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4086 int pos=(-meshDimRelToMax);
4091 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4092 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4093 * \param [in] m - the new mesh to set.
4094 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4096 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4097 * another node coordinates array.
4098 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4099 * to the existing meshes of other levels of \a this mesh.
4101 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4103 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4104 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4108 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4109 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4110 * \param [in] m - the new mesh to set.
4111 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4112 * writing \a this mesh in a MED file.
4113 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4115 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4116 * another node coordinates array.
4117 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4118 * to the existing meshes of other levels of \a this mesh.
4120 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4122 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4123 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4126 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4128 dealWithTinyInfo(m);
4129 std::vector<int> levSet=getNonEmptyLevels();
4130 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4132 if((DataArrayDouble *)_coords==0)
4134 DataArrayDouble *c=m->getCoords();
4139 if(m->getCoords()!=_coords)
4140 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4141 int sz=(-meshDimRelToMax)+1;
4142 if(sz>=(int)_ms.size())
4144 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4148 return _ms[-meshDimRelToMax];
4152 * This method allows to set at once the content of different levels in \a this.
4153 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4155 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4156 * \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.
4157 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4159 * \throw If \a there is a null pointer in \a ms.
4160 * \sa MEDFileUMesh::setMeshAtLevel
4162 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4166 const MEDCouplingUMesh *mRef=ms[0];
4168 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4169 std::string name(mRef->getName());
4170 const DataArrayDouble *coo(mRef->getCoords());
4173 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4175 const MEDCouplingUMesh *cur(*it);
4177 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4178 if(coo!=cur->getCoords())
4179 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4180 int mdim=cur->getMeshDimension();
4181 zeDim=std::max(zeDim,mdim);
4182 if(s.find(mdim)!=s.end())
4183 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4185 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4187 int mdim=(*it)->getMeshDimension();
4188 setName((*it)->getName());
4189 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4195 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4196 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4197 * The given meshes must share the same node coordinates array.
4198 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4199 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4200 * create in \a this mesh.
4201 * \throw If \a ms is empty.
4202 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4203 * to the existing meshes of other levels of \a this mesh.
4204 * \throw If the meshes in \a ms do not share the same node coordinates array.
4205 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4206 * of the given meshes.
4207 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4208 * \throw If names of some meshes in \a ms are equal.
4209 * \throw If \a ms includes a mesh with an empty name.
4211 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4214 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4215 int sz=(-meshDimRelToMax)+1;
4216 if(sz>=(int)_ms.size())
4218 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4219 DataArrayDouble *coo=checkMultiMesh(ms);
4220 if((DataArrayDouble *)_coords==0)
4226 if((DataArrayDouble *)_coords!=coo)
4227 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4228 std::vector<DataArrayInt *> corr;
4229 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4230 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4231 setMeshAtLevel(meshDimRelToMax,m,renum);
4232 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4233 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4237 * Creates groups at a given level in \a this mesh from a sequence of
4238 * meshes each representing a group.
4239 * The given meshes must share the same node coordinates array.
4240 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4241 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4242 * create in \a this mesh.
4243 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4245 * \throw If \a ms is empty.
4246 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4247 * to the existing meshes of other levels of \a this mesh.
4248 * \throw If the meshes in \a ms do not share the same node coordinates array.
4249 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4250 * of the given meshes.
4251 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4252 * \throw If names of some meshes in \a ms are equal.
4253 * \throw If \a ms includes a mesh with an empty name.
4255 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4258 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4259 int sz=(-meshDimRelToMax)+1;
4260 if(sz>=(int)_ms.size())
4262 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4263 DataArrayDouble *coo=checkMultiMesh(ms);
4264 if((DataArrayDouble *)_coords==0)
4270 if((DataArrayDouble *)_coords!=coo)
4271 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4272 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4273 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4275 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4277 DataArrayInt *arr=0;
4278 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4282 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4283 throw INTERP_KERNEL::Exception(oss.str().c_str());
4286 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4287 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4290 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4292 const DataArrayDouble *ret=ms[0]->getCoords();
4293 int mdim=ms[0]->getMeshDimension();
4294 for(unsigned int i=1;i<ms.size();i++)
4296 ms[i]->checkCoherency();
4297 if(ms[i]->getCoords()!=ret)
4298 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4299 if(ms[i]->getMeshDimension()!=mdim)
4300 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4302 return const_cast<DataArrayDouble *>(ret);
4306 * Sets the family field of a given relative dimension.
4307 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4308 * the family field is set.
4309 * \param [in] famArr - the array of the family field.
4310 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4311 * \throw If \a famArr has an invalid size.
4313 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4315 if(meshDimRelToMaxExt==1)
4322 DataArrayDouble *coo(_coords);
4324 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4325 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4330 if(meshDimRelToMaxExt>1)
4331 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4332 int traducedRk=-meshDimRelToMaxExt;
4333 if(traducedRk>=(int)_ms.size())
4334 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
4335 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4336 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4337 return _ms[traducedRk]->setFamilyArr(famArr);
4341 * Sets the optional numbers of mesh entities of a given dimension.
4342 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4343 * \param [in] renumArr - the array of the numbers.
4344 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4345 * \throw If \a renumArr has an invalid size.
4347 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4349 if(meshDimRelToMaxExt==1)
4357 DataArrayDouble *coo(_coords);
4359 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4360 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4361 renumArr->incrRef();
4362 _num_coords=renumArr;
4366 if(meshDimRelToMaxExt>1)
4367 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4368 int traducedRk=-meshDimRelToMaxExt;
4369 if(traducedRk>=(int)_ms.size())
4370 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
4371 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4372 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4373 return _ms[traducedRk]->setRenumArr(renumArr);
4377 * Sets the optional names of mesh entities of a given dimension.
4378 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4379 * \param [in] nameArr - the array of the names.
4380 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4381 * \throw If \a nameArr has an invalid size.
4383 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4385 if(meshDimRelToMaxExt==1)
4392 DataArrayDouble *coo(_coords);
4394 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4395 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4397 _name_coords=nameArr;
4400 if(meshDimRelToMaxExt>1)
4401 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4402 int traducedRk=-meshDimRelToMaxExt;
4403 if(traducedRk>=(int)_ms.size())
4404 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
4405 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4406 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4407 return _ms[traducedRk]->setNameArr(nameArr);
4410 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4412 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4413 if((const MEDFileUMeshSplitL1 *)(*it))
4414 (*it)->synchronizeTinyInfo(*this);
4418 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4420 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4422 DataArrayInt *arr=_fam_coords;
4424 arr->changeValue(oldId,newId);
4425 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4427 MEDFileUMeshSplitL1 *sp=(*it);
4430 sp->changeFamilyIdArr(oldId,newId);
4435 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4437 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4438 const DataArrayInt *da(_fam_coords);
4440 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4441 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4443 const MEDFileUMeshSplitL1 *elt(*it);
4446 da=elt->getFamilyField();
4448 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4454 void MEDFileUMesh::computeRevNum() const
4456 if((const DataArrayInt *)_num_coords)
4459 int maxValue=_num_coords->getMaxValue(pos);
4460 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4464 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4466 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4469 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4471 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4472 ret.push_back((const DataArrayInt *)_fam_nodes);
4473 ret.push_back((const DataArrayInt *)_num_nodes);
4474 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4475 ret.push_back((const DataArrayInt *)_fam_cells);
4476 ret.push_back((const DataArrayInt *)_num_cells);
4477 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4478 ret.push_back((const DataArrayInt *)_fam_faces);
4479 ret.push_back((const DataArrayInt *)_num_faces);
4480 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4481 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4482 ret.push_back((const DataArrayInt *)_rev_num_cells);
4483 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4487 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4489 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4490 if((const DataArrayInt *)_fam_nodes)
4492 int val=_fam_nodes->getMaxValue(tmp);
4493 ret=std::max(ret,std::abs(val));
4495 if((const DataArrayInt *)_fam_cells)
4497 int val=_fam_cells->getMaxValue(tmp);
4498 ret=std::max(ret,std::abs(val));
4500 if((const DataArrayInt *)_fam_faces)
4502 int val=_fam_faces->getMaxValue(tmp);
4503 ret=std::max(ret,std::abs(val));
4508 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4510 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4511 if((const DataArrayInt *)_fam_nodes)
4513 int val=_fam_nodes->getMaxValue(tmp);
4514 ret=std::max(ret,val);
4516 if((const DataArrayInt *)_fam_cells)
4518 int val=_fam_cells->getMaxValue(tmp);
4519 ret=std::max(ret,val);
4521 if((const DataArrayInt *)_fam_faces)
4523 int val=_fam_faces->getMaxValue(tmp);
4524 ret=std::max(ret,val);
4529 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4531 int ret=std::numeric_limits<int>::max(),tmp=-1;
4532 if((const DataArrayInt *)_fam_nodes)
4534 int val=_fam_nodes->getMinValue(tmp);
4535 ret=std::min(ret,val);
4537 if((const DataArrayInt *)_fam_cells)
4539 int val=_fam_cells->getMinValue(tmp);
4540 ret=std::min(ret,val);
4542 if((const DataArrayInt *)_fam_faces)
4544 int val=_fam_faces->getMinValue(tmp);
4545 ret=std::min(ret,val);
4550 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4552 if(!MEDFileMesh::isEqual(other,eps,what))
4554 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4557 what="Mesh types differ ! This is structured and other is NOT !";
4560 const DataArrayInt *famc1=_fam_nodes;
4561 const DataArrayInt *famc2=otherC->_fam_nodes;
4562 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4564 what="Mismatch of families arr on nodes ! One is defined and not other !";
4569 bool ret=famc1->isEqual(*famc2);
4572 what="Families arr on nodes differ !";
4577 famc2=otherC->_fam_cells;
4578 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4580 what="Mismatch of families arr on cells ! One is defined and not other !";
4585 bool ret=famc1->isEqual(*famc2);
4588 what="Families arr on cells differ !";
4593 famc2=otherC->_fam_faces;
4594 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4596 what="Mismatch of families arr on faces ! One is defined and not other !";
4601 bool ret=famc1->isEqual(*famc2);
4604 what="Families arr on faces differ !";
4609 famc2=otherC->_num_nodes;
4610 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4612 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4617 bool ret=famc1->isEqual(*famc2);
4620 what="Numbering arr on nodes differ !";
4625 famc2=otherC->_num_cells;
4626 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4628 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4633 bool ret=famc1->isEqual(*famc2);
4636 what="Numbering arr on cells differ !";
4641 famc2=otherC->_num_faces;
4642 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4644 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4649 bool ret=famc1->isEqual(*famc2);
4652 what="Numbering arr on faces differ !";
4656 const DataArrayAsciiChar *d1=_names_cells;
4657 const DataArrayAsciiChar *d2=otherC->_names_cells;
4658 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4660 what="Mismatch of naming arr on cells ! One is defined and not other !";
4665 bool ret=d1->isEqual(*d2);
4668 what="Naming arr on cells differ !";
4673 d2=otherC->_names_faces;
4674 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4676 what="Mismatch of naming arr on faces ! One is defined and not other !";
4681 bool ret=d1->isEqual(*d2);
4684 what="Naming arr on faces differ !";
4689 d2=otherC->_names_nodes;
4690 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4692 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4697 bool ret=d1->isEqual(*d2);
4700 what="Naming arr on nodes differ !";
4707 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4709 MEDFileMesh::clearNonDiscrAttributes();
4710 const DataArrayInt *tmp=_fam_nodes;
4712 (const_cast<DataArrayInt *>(tmp))->setName("");
4715 (const_cast<DataArrayInt *>(tmp))->setName("");
4718 (const_cast<DataArrayInt *>(tmp))->setName("");
4721 (const_cast<DataArrayInt *>(tmp))->setName("");
4724 (const_cast<DataArrayInt *>(tmp))->setName("");
4727 (const_cast<DataArrayInt *>(tmp))->setName("");
4731 * Returns ids of mesh entities contained in given families of a given dimension.
4732 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4734 * \param [in] fams - the names of the families of interest.
4735 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4736 * returned instead of ids.
4737 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4738 * numbers, if available and required, of mesh entities of the families. The caller
4739 * is to delete this array using decrRef() as it is no more needed.
4740 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4742 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4744 std::vector<int> famIds(getFamiliesIds(fams));
4745 switch(meshDimRelToMaxExt)
4749 if((const DataArrayInt *)_fam_nodes)
4751 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4753 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4755 da=_fam_nodes->getIdsEqualList(0,0);
4757 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4762 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4767 if((const DataArrayInt *)_fam_cells)
4769 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4771 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4773 da=_fam_cells->getIdsEqualList(0,0);
4775 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4780 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4785 if((const DataArrayInt *)_fam_faces)
4787 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4789 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4791 da=_fam_faces->getIdsEqualList(0,0);
4793 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
4798 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
4802 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
4804 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
4808 * Sets the family field of a given relative dimension.
4809 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4810 * the family field is set.
4811 * \param [in] famArr - the array of the family field.
4812 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4813 * \throw If \a famArr has an invalid size.
4814 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
4816 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4818 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4820 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4821 switch(meshDimRelToMaxExt)
4825 int nbCells=mesh->getNumberOfCells();
4826 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4832 int nbNodes=mesh->getNumberOfNodes();
4833 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4839 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4840 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
4845 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
4852 * Sets the optional numbers of mesh entities of a given dimension.
4853 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4854 * \param [in] renumArr - the array of the numbers.
4855 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4856 * \throw If \a renumArr has an invalid size.
4857 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4859 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4861 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4863 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4864 switch(meshDimRelToMaxExt)
4868 int nbCells=mesh->getNumberOfCells();
4869 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4870 _num_cells=renumArr;
4875 int nbNodes=mesh->getNumberOfNodes();
4876 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4877 _num_nodes=renumArr;
4882 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4883 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
4884 _num_faces=renumArr;
4888 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
4891 renumArr->incrRef();
4895 * Sets the optional names of mesh entities of a given dimension.
4896 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4897 * \param [in] nameArr - the array of the names.
4898 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4899 * \throw If \a nameArr has an invalid size.
4901 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4903 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4905 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4906 switch(meshDimRelToMaxExt)
4910 int nbCells=mesh->getNumberOfCells();
4911 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4912 _names_cells=nameArr;
4917 int nbNodes=mesh->getNumberOfNodes();
4918 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4919 _names_nodes=nameArr;
4924 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4925 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
4926 _names_cells=nameArr;
4929 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4936 * Returns the family field for mesh entities of a given dimension.
4937 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4938 * \return const DataArrayInt * - the family field. It is an array of ids of families
4939 * each mesh entity belongs to. It can be \c NULL.
4940 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4942 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
4944 switch(meshDimRelToMaxExt)
4953 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4958 * Returns the optional numbers of mesh entities of a given dimension.
4959 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4960 * \return const DataArrayInt * - the array of the entity numbers.
4961 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4962 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4964 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
4966 switch(meshDimRelToMaxExt)
4975 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4980 * Returns the optional numbers of mesh entities of a given dimension transformed using
4981 * DataArrayInt::invertArrayN2O2O2N().
4982 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4983 * \return const DataArrayInt * - the array of the entity numbers transformed using
4984 * DataArrayInt::invertArrayN2O2O2N().
4985 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4986 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4988 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
4990 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4991 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4992 if(meshDimRelToMaxExt==0)
4994 if((const DataArrayInt *)_num_cells)
4997 int maxValue=_num_cells->getMaxValue(pos);
4998 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4999 return _rev_num_cells;
5002 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5006 if((const DataArrayInt *)_num_nodes)
5009 int maxValue=_num_nodes->getMaxValue(pos);
5010 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5011 return _rev_num_nodes;
5014 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5018 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5020 switch(meshDimRelToMaxExt)
5023 return _names_cells;
5025 return _names_nodes;
5027 return _names_faces;
5029 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5034 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5035 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5037 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5039 std::vector<int> ret(1);
5044 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5045 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5047 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5049 std::vector<int> ret(2);
5055 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5057 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5059 std::vector<int> ret;
5060 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5071 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5073 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5075 std::vector<int> ret;
5076 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5087 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5089 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5091 std::vector<int> ret;
5092 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5103 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5105 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5107 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5111 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5113 DataArrayInt *arr=_fam_nodes;
5115 arr->changeValue(oldId,newId);
5118 arr->changeValue(oldId,newId);
5121 arr->changeValue(oldId,newId);
5124 void MEDFileStructuredMesh::deepCpyAttributes()
5126 if((const DataArrayInt*)_fam_nodes)
5127 _fam_nodes=_fam_nodes->deepCpy();
5128 if((const DataArrayInt*)_num_nodes)
5129 _num_nodes=_num_nodes->deepCpy();
5130 if((const DataArrayAsciiChar*)_names_nodes)
5131 _names_nodes=_names_nodes->deepCpy();
5132 if((const DataArrayInt*)_fam_cells)
5133 _fam_cells=_fam_cells->deepCpy();
5134 if((const DataArrayInt*)_num_cells)
5135 _num_cells=_num_cells->deepCpy();
5136 if((const DataArrayAsciiChar*)_names_cells)
5137 _names_cells=_names_cells->deepCpy();
5138 if((const DataArrayInt*)_fam_faces)
5139 _fam_faces=_fam_faces->deepCpy();
5140 if((const DataArrayInt*)_num_faces)
5141 _num_faces=_num_faces->deepCpy();
5142 if((const DataArrayAsciiChar*)_names_faces)
5143 _names_faces=_names_faces->deepCpy();
5144 if((const DataArrayInt*)_rev_num_nodes)
5145 _rev_num_nodes=_rev_num_nodes->deepCpy();
5146 if((const DataArrayInt*)_rev_num_cells)
5147 _rev_num_cells=_rev_num_cells->deepCpy();
5151 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5153 * \return a pointer to cartesian mesh that need to be managed by the caller.
5154 * \warning the returned pointer has to be managed by the caller.
5158 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5159 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5160 * \param [in] renum - it must be \c false.
5161 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5162 * delete using decrRef() as it is no more needed.
5164 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
5167 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5168 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5169 switch(meshDimRelToMax)
5175 return const_cast<MEDCouplingStructuredMesh *>(m);
5180 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5181 buildMinusOneImplicitPartIfNeeded();
5182 MEDCouplingMesh *ret(_faces_if_necessary);
5188 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5193 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5194 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5195 * \return int - the number of entities.
5196 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5198 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5200 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5202 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5203 switch(meshDimRelToMaxExt)
5206 return cmesh->getNumberOfCells();
5208 return cmesh->getNumberOfNodes();
5210 return cmesh->getNumberOfCellsOfSubLevelMesh();
5212 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5216 int MEDFileStructuredMesh::getNumberOfNodes() const
5218 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5220 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5221 return cmesh->getNumberOfNodes();
5224 bool MEDFileStructuredMesh::hasImplicitPart() const
5230 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5232 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5234 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5235 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5238 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5239 if(cm.getReverseExtrudedType()!=gt)
5240 throw INTERP_KERNEL::Exception(MSG);
5241 buildImplicitPart();
5242 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5246 if(gt!=zeFaceMesh->getCellModelEnum())
5247 throw INTERP_KERNEL::Exception(MSG);
5248 return zeFaceMesh->getNumberOfCells();
5252 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5254 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5256 buildImplicitPart();
5259 void MEDFileStructuredMesh::buildImplicitPart() const
5261 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5263 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5264 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5267 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5269 _faces_if_necessary=0;
5273 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5274 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5276 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5278 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5280 return _faces_if_necessary;
5283 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5285 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5287 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5288 switch(meshDimRelToMax)
5292 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5297 int mdim(cmesh->getMeshDimension());
5299 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5300 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5304 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5308 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5310 if(st.getNumberOfItems()!=1)
5311 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 !");
5312 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5313 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5314 if(getNumberOfNodes()!=(int)nodesFetched.size())
5315 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5316 if(st[0].getPflName().empty())
5318 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5321 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5322 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5323 int sz(nodesFetched.size());
5324 for(const int *work=arr->begin();work!=arr->end();work++)
5326 std::vector<int> conn;
5327 cmesh->getNodeIdsOfCell(*work,conn);
5328 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5329 if(*it>=0 && *it<sz)
5330 nodesFetched[*it]=true;
5332 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5336 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5338 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5342 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5343 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5345 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5346 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5348 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5351 if(!mrs || mrs->isCellFamilyFieldReading())
5353 famCells=DataArrayInt::New();
5354 famCells->alloc(nbOfElt,1);
5355 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
5358 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5361 if(!mrs || mrs->isCellNumFieldReading())
5363 numCells=DataArrayInt::New();
5364 numCells->alloc(nbOfElt,1);
5365 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
5368 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5371 if(!mrs || mrs->isCellNameFieldReading())
5373 namesCells=DataArrayAsciiChar::New();
5374 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5375 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
5376 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5381 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5383 setName(strm->getName());
5384 setDescription(strm->getDescription());
5385 setUnivName(strm->getUnivName());
5386 setIteration(strm->getIteration());
5387 setOrder(strm->getOrder());
5388 setTimeValue(strm->getTime());
5389 setTimeUnit(strm->getTimeUnit());
5390 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5391 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5392 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5395 if(!mrs || mrs->isNodeFamilyFieldReading())
5397 int nbNodes(getNumberOfNodes());
5399 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5400 _fam_nodes=DataArrayInt::New();
5401 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5402 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...
5403 _fam_nodes->fillWithZero();
5404 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
5407 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5410 if(!mrs || mrs->isNodeNumFieldReading())
5412 _num_nodes=DataArrayInt::New();
5413 _num_nodes->alloc(nbOfElt,1);
5414 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
5417 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5420 if(!mrs || mrs->isNodeNameFieldReading())
5422 _names_nodes=DataArrayAsciiChar::New();
5423 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5424 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
5425 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5428 int meshDim(getStructuredMesh()->getMeshDimension());
5429 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5431 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5434 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5436 int meshDim(getStructuredMesh()->getMeshDimension());
5437 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5439 if((const DataArrayInt *)_fam_cells)
5440 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
5441 if((const DataArrayInt *)_fam_faces)
5442 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
5443 if((const DataArrayInt *)_fam_nodes)
5444 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
5445 if((const DataArrayInt *)_num_cells)
5446 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
5447 if((const DataArrayInt *)_num_faces)
5448 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
5449 if((const DataArrayInt *)_num_nodes)
5450 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
5451 if((const DataArrayAsciiChar *)_names_cells)
5453 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5455 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5456 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5457 throw INTERP_KERNEL::Exception(oss.str().c_str());
5459 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
5461 if((const DataArrayAsciiChar *)_names_faces)
5463 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5465 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5466 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5467 throw INTERP_KERNEL::Exception(oss.str().c_str());
5469 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
5471 if((const DataArrayAsciiChar *)_names_nodes)
5473 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5475 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5476 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5477 throw INTERP_KERNEL::Exception(oss.str().c_str());
5479 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
5482 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5486 * Returns an empty instance of MEDFileCMesh.
5487 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5488 * mesh using decrRef() as it is no more needed.
5490 MEDFileCMesh *MEDFileCMesh::New()
5492 return new MEDFileCMesh;
5496 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5497 * file. The first mesh in the file is loaded.
5498 * \param [in] fileName - the name of MED file to read.
5499 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5500 * mesh using decrRef() as it is no more needed.
5501 * \throw If the file is not readable.
5502 * \throw If there is no meshes in the file.
5503 * \throw If the mesh in the file is not a Cartesian one.
5505 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5507 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5510 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5511 throw INTERP_KERNEL::Exception(oss.str().c_str());
5513 MEDFileUtilities::CheckFileForRead(fileName);
5514 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5516 ParaMEDMEM::MEDCouplingMeshType meshType;
5518 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5519 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5523 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5524 * file. The mesh to load is specified by its name and numbers of a time step and an
5526 * \param [in] fileName - the name of MED file to read.
5527 * \param [in] mName - the name of the mesh to read.
5528 * \param [in] dt - the number of a time step.
5529 * \param [in] it - the number of an iteration.
5530 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5531 * mesh using decrRef() as it is no more needed.
5532 * \throw If the file is not readable.
5533 * \throw If there is no mesh with given attributes in the file.
5534 * \throw If the mesh in the file is not a Cartesian one.
5536 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5538 MEDFileUtilities::CheckFileForRead(fileName);
5539 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5540 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5543 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5545 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5548 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5550 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5551 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5556 * Returns the dimension on cells in \a this mesh.
5557 * \return int - the mesh dimension.
5558 * \throw If there are no cells in this mesh.
5560 int MEDFileCMesh::getMeshDimension() const
5562 if(!((const MEDCouplingCMesh*)_cmesh))
5563 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5564 return _cmesh->getMeshDimension();
5568 * Returns the dimension on nodes in \a this mesh.
5569 * \return int - the space dimension.
5570 * \throw If there are no cells in this mesh.
5572 int MEDFileCMesh::getSpaceDimension() const
5574 if(!((const MEDCouplingCMesh*)_cmesh))
5575 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5576 return _cmesh->getSpaceDimension();
5580 * Returns a string describing \a this mesh.
5581 * \return std::string - the mesh information string.
5583 std::string MEDFileCMesh::simpleRepr() const
5585 return MEDFileStructuredMesh::simpleRepr();
5589 * Returns a full textual description of \a this mesh.
5590 * \return std::string - the string holding the mesh description.
5592 std::string MEDFileCMesh::advancedRepr() const
5594 return simpleRepr();
5597 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5599 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5603 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5605 return new MEDFileCMesh;
5608 MEDFileMesh *MEDFileCMesh::deepCpy() const
5610 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5611 if((const MEDCouplingCMesh*)_cmesh)
5612 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5613 ret->deepCpyAttributes();
5618 * Checks if \a this and another mesh are equal.
5619 * \param [in] other - the mesh to compare with.
5620 * \param [in] eps - a precision used to compare real values.
5621 * \param [in,out] what - the string returning description of unequal data.
5622 * \return bool - \c true if the meshes are equal, \c false, else.
5624 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5626 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5628 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5631 what="Mesh types differ ! This is cartesian and other is NOT !";
5634 clearNonDiscrAttributes();
5635 otherC->clearNonDiscrAttributes();
5636 const MEDCouplingCMesh *coo1=_cmesh;
5637 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5638 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5640 what="Mismatch of cartesian meshes ! One is defined and not other !";
5645 bool ret=coo1->isEqual(coo2,eps);
5648 what="cartesian meshes differ !";
5656 * Clears redundant attributes of incorporated data arrays.
5658 void MEDFileCMesh::clearNonDiscrAttributes() const
5660 MEDFileStructuredMesh::clearNonDiscrAttributes();
5661 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
5664 MEDFileCMesh::MEDFileCMesh()
5668 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5671 loadCMeshFromFile(fid,mName,dt,it,mrs);
5673 catch(INTERP_KERNEL::Exception& e)
5678 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5680 ParaMEDMEM::MEDCouplingMeshType meshType;
5683 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5684 if(meshType!=CARTESIAN)
5686 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
5687 throw INTERP_KERNEL::Exception(oss.str().c_str());
5689 MEDFileCMeshL2 loaderl2;
5690 loaderl2.loadAll(fid,mid,mName,dt,it);
5691 MEDCouplingCMesh *mesh=loaderl2.getMesh();
5694 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5698 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
5699 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
5701 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
5703 synchronizeTinyInfoOnLeaves();
5707 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
5709 synchronizeTinyInfoOnLeaves();
5714 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
5715 * \param [in] m - the new MEDCouplingCMesh to refer to.
5716 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5719 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
5721 dealWithTinyInfo(m);
5727 void MEDFileCMesh::writeLL(med_idt fid) const
5729 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5730 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5731 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5732 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5733 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5734 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5735 int spaceDim(_cmesh->getSpaceDimension());
5736 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5737 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5738 for(int i=0;i<spaceDim;i++)
5740 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
5742 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5743 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
5744 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
5746 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5747 MEDmeshUniversalNameWr(fid,maa);
5748 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
5749 for(int i=0;i<spaceDim;i++)
5751 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
5752 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
5755 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5756 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5759 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
5761 const MEDCouplingCMesh *cmesh=_cmesh;
5764 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
5765 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
5766 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
5767 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
5770 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
5772 return new MEDFileCurveLinearMesh;
5775 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5777 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5780 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5781 throw INTERP_KERNEL::Exception(oss.str().c_str());
5783 MEDFileUtilities::CheckFileForRead(fileName);
5784 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5786 ParaMEDMEM::MEDCouplingMeshType meshType;
5788 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5789 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
5792 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5794 MEDFileUtilities::CheckFileForRead(fileName);
5795 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5796 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
5799 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
5801 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5804 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
5806 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5807 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5811 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5813 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5817 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5819 return new MEDFileCurveLinearMesh;
5822 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5824 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5825 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5826 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5827 ret->deepCpyAttributes();
5831 int MEDFileCurveLinearMesh::getMeshDimension() const
5833 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5834 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5835 return _clmesh->getMeshDimension();
5838 std::string MEDFileCurveLinearMesh::simpleRepr() const
5840 return MEDFileStructuredMesh::simpleRepr();
5843 std::string MEDFileCurveLinearMesh::advancedRepr() const
5845 return simpleRepr();
5848 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5850 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5852 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5855 what="Mesh types differ ! This is curve linear and other is NOT !";
5858 clearNonDiscrAttributes();
5859 otherC->clearNonDiscrAttributes();
5860 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5861 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5862 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5864 what="Mismatch of curve linear meshes ! One is defined and not other !";
5869 bool ret=coo1->isEqual(coo2,eps);
5872 what="curve linear meshes differ !";
5879 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
5881 MEDFileStructuredMesh::clearNonDiscrAttributes();
5882 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
5885 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
5887 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
5890 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
5891 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
5892 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
5893 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
5896 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
5898 synchronizeTinyInfoOnLeaves();
5902 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
5904 dealWithTinyInfo(m);
5910 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
5912 synchronizeTinyInfoOnLeaves();
5916 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
5920 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5923 loadCLMeshFromFile(fid,mName,dt,it,mrs);
5925 catch(INTERP_KERNEL::Exception& e)
5930 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
5932 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5933 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5934 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5935 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5936 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5937 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5938 int spaceDim=_clmesh->getSpaceDimension();
5939 int meshDim=_clmesh->getMeshDimension();
5940 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5941 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5942 const DataArrayDouble *coords=_clmesh->getCoords();
5944 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5945 for(int i=0;i<spaceDim;i++)
5947 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5949 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5950 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
5951 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
5953 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5954 MEDmeshUniversalNameWr(fid,maa);
5955 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5956 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5957 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5959 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5961 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5962 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5965 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5967 ParaMEDMEM::MEDCouplingMeshType meshType;
5970 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5971 if(meshType!=CURVE_LINEAR)
5973 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5974 throw INTERP_KERNEL::Exception(oss.str().c_str());
5976 MEDFileCLMeshL2 loaderl2;
5977 loaderl2.loadAll(fid,mid,mName,dt,it);
5978 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5981 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5984 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5986 return new MEDFileMeshMultiTS;
5989 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
5991 return new MEDFileMeshMultiTS(fileName);
5994 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
5996 return new MEDFileMeshMultiTS(fileName,mName);
5999 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6001 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6002 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6004 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6005 if((const MEDFileMesh *)*it)
6006 meshOneTs[i]=(*it)->deepCpy();
6007 ret->_mesh_one_ts=meshOneTs;
6011 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6013 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6016 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6018 std::vector<const BigMemoryObject *> ret;
6019 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6020 ret.push_back((const MEDFileMesh *)*it);
6024 std::string MEDFileMeshMultiTS::getName() const
6026 if(_mesh_one_ts.empty())
6027 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6028 return _mesh_one_ts[0]->getName();
6031 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6033 std::string oldName(getName());
6034 std::vector< std::pair<std::string,std::string> > v(1);
6035 v[0].first=oldName; v[0].second=newMeshName;
6039 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6042 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6044 MEDFileMesh *cur(*it);
6046 ret=cur->changeNames(modifTab) || ret;
6051 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6053 if(_mesh_one_ts.empty())
6054 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6055 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6058 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6061 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6062 _mesh_one_ts.resize(1);
6063 mesh1TimeStep->incrRef();
6064 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6065 _mesh_one_ts[0]=mesh1TimeStep;
6068 void MEDFileMeshMultiTS::write(med_idt fid) const
6070 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6072 (*it)->copyOptionsFrom(*this);
6077 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6079 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6080 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6081 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6082 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6086 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6087 {//for the moment to be improved
6088 _mesh_one_ts.resize(1);
6089 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
6092 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6096 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6099 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6102 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6103 throw INTERP_KERNEL::Exception(oss.str().c_str());
6105 MEDFileUtilities::CheckFileForRead(fileName);
6106 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6108 ParaMEDMEM::MEDCouplingMeshType meshType;
6110 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6111 loadFromFile(fileName,ms.front());
6113 catch(INTERP_KERNEL::Exception& e)
6118 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6121 loadFromFile(fileName,mName);
6123 catch(INTERP_KERNEL::Exception& e)
6128 MEDFileMeshes *MEDFileMeshes::New()
6130 return new MEDFileMeshes;
6133 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6135 return new MEDFileMeshes(fileName);
6138 void MEDFileMeshes::write(med_idt fid) const
6141 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6143 (*it)->copyOptionsFrom(*this);
6148 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6150 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6151 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6152 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6153 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6158 int MEDFileMeshes::getNumberOfMeshes() const
6160 return _meshes.size();
6163 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6165 return new MEDFileMeshesIterator(this);
6168 /** Return a borrowed reference (caller is not responsible) */
6169 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6171 if(i<0 || i>=(int)_meshes.size())
6173 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6174 throw INTERP_KERNEL::Exception(oss.str().c_str());
6176 return _meshes[i]->getOneTimeStep();
6179 /** Return a borrowed reference (caller is not responsible) */
6180 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6182 std::vector<std::string> ms=getMeshesNames();
6183 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6186 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6187 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6188 throw INTERP_KERNEL::Exception(oss.str().c_str());
6190 return getMeshAtPos((int)std::distance(ms.begin(),it));
6193 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6195 std::vector<std::string> ret(_meshes.size());
6197 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6199 const MEDFileMeshMultiTS *f=(*it);
6202 ret[i]=f->getName();
6206 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6207 throw INTERP_KERNEL::Exception(oss.str().c_str());
6213 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6216 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6218 MEDFileMeshMultiTS *cur(*it);
6220 ret=cur->changeNames(modifTab) || ret;
6225 void MEDFileMeshes::resize(int newSize)
6227 _meshes.resize(newSize);
6230 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6233 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6234 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6235 elt->setOneTimeStep(mesh);
6236 _meshes.push_back(elt);
6239 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6242 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6243 if(i>=(int)_meshes.size())
6244 _meshes.resize(i+1);
6245 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6246 elt->setOneTimeStep(mesh);
6250 void MEDFileMeshes::destroyMeshAtPos(int i)
6252 if(i<0 || i>=(int)_meshes.size())
6254 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6255 throw INTERP_KERNEL::Exception(oss.str().c_str());
6257 _meshes.erase(_meshes.begin()+i);
6260 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6262 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6264 _meshes.resize(ms.size());
6265 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6266 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6269 MEDFileMeshes::MEDFileMeshes()
6273 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6276 loadFromFile(fileName);
6278 catch(INTERP_KERNEL::Exception& /*e*/)
6282 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6284 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6286 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6287 if((const MEDFileMeshMultiTS *)*it)
6288 meshes[i]=(*it)->deepCpy();
6289 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6290 ret->_meshes=meshes;
6294 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6296 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6299 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6301 std::vector<const BigMemoryObject *> ret;
6302 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6303 ret.push_back((const MEDFileMeshMultiTS *)*it);
6307 std::string MEDFileMeshes::simpleRepr() const
6309 std::ostringstream oss;
6310 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6311 simpleReprWithoutHeader(oss);
6315 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6317 int nbOfMeshes=getNumberOfMeshes();
6318 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6319 std::vector<std::string> mns=getMeshesNames();
6320 for(int i=0;i<nbOfMeshes;i++)
6321 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6324 void MEDFileMeshes::checkCoherency() const
6326 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6328 std::set<std::string> s;
6329 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6331 const MEDFileMeshMultiTS *elt=(*it);
6334 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6335 throw INTERP_KERNEL::Exception(oss.str().c_str());
6337 std::size_t sz=s.size();
6338 s.insert(std::string((*it)->getName()));
6341 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6342 throw INTERP_KERNEL::Exception(oss.str().c_str());
6347 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6352 _nb_iter=ms->getNumberOfMeshes();
6356 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6360 MEDFileMesh *MEDFileMeshesIterator::nextt()
6362 if(_iter_id<_nb_iter)
6364 MEDFileMeshes *ms(_ms);
6366 return ms->getMeshAtPos(_iter_id++);