1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileUtilities.hxx"
23 #include "MEDFileFieldOverView.hxx"
24 #include "MEDFileField.hxx"
25 #include "MEDLoader.hxx"
26 #include "MEDLoaderBase.hxx"
28 #include "MEDCouplingUMesh.hxx"
30 #include "InterpKernelAutoPtr.hxx"
35 extern med_geometry_type typmai3[34];
37 using namespace ParaMEDMEM;
39 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
41 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
45 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
47 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
48 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
50 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
51 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
52 ret+=(*it2).capacity();
54 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
55 ret+=(*it).first.capacity()+sizeof(int);
59 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
61 return std::vector<const BigMemoryObject *>();
65 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
66 * file. The first mesh in the file is loaded.
67 * \param [in] fileName - the name of MED file to read.
68 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
69 * mesh using decrRef() as it is no more needed.
70 * \throw If the file is not readable.
71 * \throw If there is no meshes in the file.
72 * \throw If the mesh in the file is of a not supported type.
74 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
76 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
79 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
80 throw INTERP_KERNEL::Exception(oss.str().c_str());
82 MEDFileUtilities::CheckFileForRead(fileName);
83 ParaMEDMEM::MEDCouplingMeshType meshType;
84 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
87 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
92 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
93 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
94 return (MEDFileUMesh *)ret.retn();
98 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
99 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
100 return (MEDFileCMesh *)ret.retn();
104 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
105 ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
106 return (MEDFileCurveLinearMesh *)ret.retn();
110 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
111 throw INTERP_KERNEL::Exception(oss.str().c_str());
117 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
118 * file. The mesh to load is specified by its name and numbers of a time step and an
120 * \param [in] fileName - the name of MED file to read.
121 * \param [in] mName - the name of the mesh to read.
122 * \param [in] dt - the number of a time step.
123 * \param [in] it - the number of an iteration.
124 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
125 * mesh using decrRef() as it is no more needed.
126 * \throw If the file is not readable.
127 * \throw If there is no mesh with given attributes in the file.
128 * \throw If the mesh in the file is of a not supported type.
130 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
132 MEDFileUtilities::CheckFileForRead(fileName);
133 ParaMEDMEM::MEDCouplingMeshType meshType;
134 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
137 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
142 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
143 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
144 return (MEDFileUMesh *)ret.retn();
148 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
149 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
150 return (MEDFileCMesh *)ret.retn();
154 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
155 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
156 return (MEDFileCurveLinearMesh *)ret.retn();
160 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
161 throw INTERP_KERNEL::Exception(oss.str().c_str());
167 * Writes \a this mesh into an open MED file specified by its descriptor.
168 * \param [in] fid - the MED file descriptor.
169 * \throw If the mesh name is not set.
170 * \throw If the file is open for reading only.
171 * \throw If the writing mode == 1 and the same data is present in an existing file.
173 void MEDFileMesh::write(med_idt fid) const
176 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
178 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
183 * Writes \a this mesh into a MED file specified by its name.
184 * \param [in] fileName - the MED file name.
185 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
186 * - 2 - erase; an existing file is removed.
187 * - 1 - append; same data should not be present in an existing file.
188 * - 0 - overwrite; same data present in an existing file is overwritten.
189 * \throw If the mesh name is not set.
190 * \throw If \a mode == 1 and the same data is present in an existing file.
192 void MEDFileMesh::write(const std::string& fileName, int mode) const
194 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
195 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
196 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
197 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
202 * Checks if \a this and another mesh are equal.
203 * \param [in] other - the mesh to compare with.
204 * \param [in] eps - a precision used to compare real values.
205 * \param [in,out] what - the string returning description of unequal data.
206 * \return bool - \c true if the meshes are equal, \c false, else.
208 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
210 if(_order!=other->_order)
212 what="Orders differ !";
215 if(_iteration!=other->_iteration)
217 what="Iterations differ !";
220 if(fabs(_time-other->_time)>eps)
222 what="Time values differ !";
225 if(_dt_unit!=other->_dt_unit)
227 what="Time units differ !";
230 if(_name!=other->_name)
232 what="Names differ !";
235 //univ_name has been ignored -> not a bug because it is a mutable attribute
236 if(_desc_name!=other->_desc_name)
238 what="Description names differ !";
241 if(!areGrpsEqual(other,what))
243 if(!areFamsEqual(other,what))
248 void MEDFileMesh::setName(const std::string& name)
254 * Clears redundant attributes of incorporated data arrays.
256 void MEDFileMesh::clearNonDiscrAttributes() const
261 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
263 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
265 if((*it).first==_name)
275 * Copies data on groups and families from another mesh.
276 * \param [in] other - the mesh to copy the data from.
278 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
280 _groups=other._groups;
281 _families=other._families;
286 * This method clear all the groups in the map.
287 * So this method does not operate at all on arrays.
288 * So this method can lead to orphan families.
290 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
292 void MEDFileMesh::clearGrpMap()
298 * This method clear all the families in the map.
299 * So this method does not operate at all on arrays.
300 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
302 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
304 void MEDFileMesh::clearFamMap()
310 * This method clear all the families and groups in the map.
311 * So this method does not operate at all on arrays.
312 * As all groups and families entry will be removed after
313 * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object.
315 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
317 void MEDFileMesh::clearFamGrpMaps()
324 * Returns names of families constituting a group.
325 * \param [in] name - the name of the group of interest.
326 * \return std::vector<std::string> - a sequence of names of the families.
327 * \throw If the name of a nonexistent group is specified.
329 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
331 std::string oname(name);
332 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
333 if(it==_groups.end())
335 std::vector<std::string> grps=getGroupsNames();
336 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
337 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
338 throw INTERP_KERNEL::Exception(oss.str().c_str());
344 * Returns names of families constituting some groups.
345 * \param [in] grps - a sequence of names of groups of interest.
346 * \return std::vector<std::string> - a sequence of names of the families.
347 * \throw If a name of a nonexistent group is present in \a grps.
349 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
351 std::set<std::string> fams;
352 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
354 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
355 if(it2==_groups.end())
357 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
358 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
359 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
360 throw INTERP_KERNEL::Exception(oss.str().c_str());
362 fams.insert((*it2).second.begin(),(*it2).second.end());
364 std::vector<std::string> fams2(fams.begin(),fams.end());
369 * Returns ids of families constituting a group.
370 * \param [in] name - the name of the group of interest.
371 * \return std::vector<int> - sequence of ids of the families.
372 * \throw If the name of a nonexistent group is specified.
374 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
376 std::string oname(name);
377 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
378 std::vector<std::string> grps=getGroupsNames();
379 if(it==_groups.end())
381 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
382 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
383 throw INTERP_KERNEL::Exception(oss.str().c_str());
385 return getFamiliesIds((*it).second);
389 * Sets names of families constituting a group. If data on families of this group is
390 * already present, it is overwritten. Every family in \a fams is checked, and if a
391 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
392 * \param [in] name - the name of the group of interest.
393 * \param [in] fams - a sequence of names of families constituting the group.
395 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
397 std::string oname(name);
399 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
401 std::map<std::string,int>::iterator it2=_families.find(*it1);
402 if(it2==_families.end())
408 * Sets families constituting a group. The families are specified by their ids.
409 * If a family name is not found by its id, an exception is thrown.
410 * If several families have same id, the first one in lexical order is taken.
411 * \param [in] name - the name of the group of interest.
412 * \param [in] famIds - a sequence of ids of families constituting the group.
413 * \throw If a family name is not found by its id.
415 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
417 std::string oname(name);
418 std::vector<std::string> fams(famIds.size());
420 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
422 std::string name2=getFamilyNameGivenId(*it1);
429 * Returns names of groups including a given family.
430 * \param [in] name - the name of the family of interest.
431 * \return std::vector<std::string> - a sequence of names of groups including the family.
433 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
435 std::vector<std::string> ret;
436 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
438 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
441 ret.push_back((*it1).first);
449 * Adds an existing family to groups.
450 * \param [in] famName - a name of family to add to \a grps.
451 * \param [in] grps - a sequence of group names to add the family in.
452 * \throw If a family named \a famName not yet exists.
454 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
456 std::string fName(famName);
457 const std::map<std::string,int>::const_iterator it=_families.find(fName);
458 if(it==_families.end())
460 std::vector<std::string> fams=getFamiliesNames();
461 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
462 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
463 throw INTERP_KERNEL::Exception(oss.str().c_str());
465 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
467 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
468 if(it2!=_groups.end())
469 (*it2).second.push_back(fName);
472 std::vector<std::string> grps2(1,fName);
479 * Returns names of all groups of \a this mesh.
480 * \return std::vector<std::string> - a sequence of group names.
482 std::vector<std::string> MEDFileMesh::getGroupsNames() const
484 std::vector<std::string> ret(_groups.size());
486 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
492 * Returns names of all families of \a this mesh.
493 * \return std::vector<std::string> - a sequence of family names.
495 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
497 std::vector<std::string> ret(_families.size());
499 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
505 * Changes a name of every family, included in one group only, to be same as the group name.
506 * \throw If there are families with equal names in \a this mesh.
508 void MEDFileMesh::assignFamilyNameWithGroupName()
510 std::map<std::string, std::vector<std::string> > groups(_groups);
511 std::map<std::string,int> newFams;
512 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
514 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
515 if(grps.size()==1 && groups[grps[0]].size()==1)
517 if(newFams.find(grps[0])!=newFams.end())
519 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
520 throw INTERP_KERNEL::Exception(oss.str().c_str());
522 newFams[grps[0]]=(*it).second;
523 std::vector<std::string>& grps2=groups[grps[0]];
524 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
529 if(newFams.find((*it).first)!=newFams.end())
531 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
532 throw INTERP_KERNEL::Exception(oss.str().c_str());
534 newFams[(*it).first]=(*it).second;
542 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
544 * \return the removed groups.
546 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
548 std::vector<std::string> ret;
549 std::map<std::string, std::vector<std::string> > newGrps;
550 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
552 if((*it).second.empty())
553 ret.push_back((*it).first);
555 newGrps[(*it).first]=(*it).second;
563 * Removes a group from \a this mesh.
564 * \param [in] name - the name of the group to remove.
565 * \throw If no group with such a \a name exists.
567 void MEDFileMesh::removeGroup(const std::string& name)
569 std::string oname(name);
570 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
571 std::vector<std::string> grps=getGroupsNames();
572 if(it==_groups.end())
574 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
575 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
576 throw INTERP_KERNEL::Exception(oss.str().c_str());
582 * Removes a family from \a this mesh.
583 * \param [in] name - the name of the family to remove.
584 * \throw If no family with such a \a name exists.
586 void MEDFileMesh::removeFamily(const std::string& name)
588 std::string oname(name);
589 std::map<std::string, int >::iterator it=_families.find(oname);
590 std::vector<std::string> fams=getFamiliesNames();
591 if(it==_families.end())
593 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
594 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
595 throw INTERP_KERNEL::Exception(oss.str().c_str());
598 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
600 std::vector<std::string>& v=(*it3).second;
601 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
608 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
609 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
610 * family field whatever its level. This method also suppresses the orphan families.
612 * \return - The list of removed groups names.
614 * \sa MEDFileMesh::removeOrphanFamilies.
616 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
618 removeOrphanFamilies();
619 return removeEmptyGroups();
623 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
624 * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified.
626 * \return - The list of removed families names.
627 * \sa MEDFileMesh::removeOrphanGroups.
629 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
632 std::vector<std::string> ret;
633 if(!((DataArrayInt*)allFamIdsInUse))
635 ret=getFamiliesNames();
636 _families.clear(); _groups.clear();
639 std::map<std::string,int> famMap;
640 std::map<std::string, std::vector<std::string> > grps(_groups);
641 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
643 if(allFamIdsInUse->presenceOfValue((*it).second))
644 famMap[(*it).first]=(*it).second;
647 ret.push_back((*it).first);
648 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
649 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
651 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
652 std::vector<std::string>& famv=(*it3).second;
653 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
659 { _families=famMap; _groups=grps; }
664 * Renames a group in \a this mesh.
665 * \param [in] oldName - a current name of the group to rename.
666 * \param [in] newName - a new group name.
667 * \throw If no group named \a oldName exists in \a this mesh.
668 * \throw If a group named \a newName already exists.
670 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
672 std::string oname(oldName);
673 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
674 std::vector<std::string> grps=getGroupsNames();
675 if(it==_groups.end())
677 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
678 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
679 throw INTERP_KERNEL::Exception(oss.str().c_str());
681 std::string nname(newName);
682 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
683 if(it2!=_groups.end())
685 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
686 throw INTERP_KERNEL::Exception(oss.str().c_str());
688 std::vector<std::string> cpy=(*it).second;
690 _groups[newName]=cpy;
694 * Changes an id of a family in \a this mesh.
695 * This method calls changeFamilyIdArr().
696 * \param [in] oldId - a current id of the family.
697 * \param [in] newId - a new family id.
699 void MEDFileMesh::changeFamilyId(int oldId, int newId)
701 changeFamilyIdArr(oldId,newId);
702 std::map<std::string,int> fam2;
703 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
705 if((*it).second==oldId)
706 fam2[(*it).first]=newId;
708 fam2[(*it).first]=(*it).second;
714 * Renames a family in \a this mesh.
715 * \param [in] oldName - a current name of the family to rename.
716 * \param [in] newName - a new family name.
717 * \throw If no family named \a oldName exists in \a this mesh.
718 * \throw If a family named \a newName already exists.
720 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
722 std::string oname(oldName);
723 std::map<std::string, int >::iterator it=_families.find(oname);
724 std::vector<std::string> fams=getFamiliesNames();
725 if(it==_families.end())
727 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
728 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
729 throw INTERP_KERNEL::Exception(oss.str().c_str());
731 std::string nname(newName);
732 std::map<std::string, int >::iterator it2=_families.find(nname);
733 if(it2!=_families.end())
735 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
736 throw INTERP_KERNEL::Exception(oss.str().c_str());
738 int cpy=(*it).second;
740 _families[newName]=cpy;
741 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
743 std::vector<std::string>& v=(*it3).second;
744 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
751 * Checks if \a this and another mesh contains the same families.
752 * \param [in] other - the mesh to compare with \a this one.
753 * \param [in,out] what - an unused parameter.
754 * \return bool - \c true if number of families and their ids are the same in the two
755 * meshes. Families with the id == \c 0 are not considered.
757 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
759 if(_families==other->_families)
761 std::map<std::string,int> fam0;
762 std::map<std::string,int> fam1;
763 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
765 fam0[(*it).first]=(*it).second;
766 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
768 fam1[(*it).first]=(*it).second;
773 * Checks if \a this and another mesh contains the same groups.
774 * \param [in] other - the mesh to compare with \a this one.
775 * \param [in,out] what - a string describing a difference of groups of the two meshes
776 * in case if this method returns \c false.
777 * \return bool - \c true if number of groups and families constituting them are the
778 * same in the two meshes.
780 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
782 if(_groups==other->_groups)
785 std::size_t sz=_groups.size();
786 if(sz!=other->_groups.size())
788 what="Groups differ because not same number !\n";
793 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
794 for(std::size_t i=0;i<sz && ret;i++,it1++)
796 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
797 if(it2!=other->_groups.end())
799 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
800 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
806 what="A group in first mesh exists not in other !\n";
812 std::ostringstream oss; oss << "Groups description differs :\n";
813 oss << "First group description :\n";
814 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
816 oss << " Group \"" << (*it).first << "\" on following families :\n";
817 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
818 oss << " \"" << *it2 << "\n";
820 oss << "Second group description :\n";
821 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
823 oss << " Group \"" << (*it).first << "\" on following families :\n";
824 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
825 oss << " \"" << *it2 << "\n";
833 * Checks if a group with a given name exists in \a this mesh.
834 * \param [in] groupName - the group name.
835 * \return bool - \c true the group \a groupName exists in \a this mesh.
837 bool MEDFileMesh::existsGroup(const std::string& groupName) const
839 std::string grpName(groupName);
840 return _groups.find(grpName)!=_groups.end();
844 * Checks if a family with a given id exists in \a this mesh.
845 * \param [in] famId - the family id.
846 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
848 bool MEDFileMesh::existsFamily(int famId) const
850 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
851 if((*it2).second==famId)
857 * Checks if a family with a given name exists in \a this mesh.
858 * \param [in] familyName - the family name.
859 * \return bool - \c true the family \a familyName exists in \a this mesh.
861 bool MEDFileMesh::existsFamily(const std::string& familyName) const
863 std::string fname(familyName);
864 return _families.find(fname)!=_families.end();
868 * Sets an id of a family.
869 * \param [in] familyName - the family name.
870 * \param [in] id - a new id of the family.
872 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
874 std::string fname(familyName);
878 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
880 std::string fname(familyName);
881 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
884 if((*it).first!=familyName)
886 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
887 throw INTERP_KERNEL::Exception(oss.str().c_str());
894 * Adds a family to \a this mesh.
895 * \param [in] familyName - a name of the family.
896 * \param [in] famId - an id of the family.
897 * \throw If a family with the same name or id already exists in \a this mesh.
899 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
901 std::string fname(familyName);
902 std::map<std::string,int>::const_iterator it=_families.find(fname);
903 if(it==_families.end())
905 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
906 if((*it2).second==famId)
908 std::ostringstream oss;
909 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
910 throw INTERP_KERNEL::Exception(oss.str().c_str());
912 _families[fname]=famId;
916 if((*it).second!=famId)
918 std::ostringstream oss;
919 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
920 throw INTERP_KERNEL::Exception(oss.str().c_str());
926 * Creates a group including all mesh entities of given dimension.
927 * \warning This method does \b not guarantee that the created group includes mesh
928 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
929 * present in family fields of different dimensions. To assure this, call
930 * ensureDifferentFamIdsPerLevel() \b before calling this method.
931 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
933 * \param [in] groupName - a name of the new group.
934 * \throw If a group named \a groupName already exists.
935 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
936 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
938 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
940 std::string grpName(groupName);
941 std::vector<int> levs=getNonEmptyLevelsExt();
942 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
944 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
945 oss << "Available relative ext levels are : ";
946 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
947 throw INTERP_KERNEL::Exception(oss.str().c_str());
949 if(existsGroup(groupName))
951 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
952 oss << "Already existing groups are : ";
953 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
954 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
955 throw INTERP_KERNEL::Exception(oss.str().c_str());
957 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
959 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
960 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
961 std::vector<std::string> familiesOnWholeGroup;
962 for(const int *it=famIds->begin();it!=famIds->end();it++)
965 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
967 _groups[grpName]=familiesOnWholeGroup;
971 * Ensures that given family ids do not present in family fields of dimensions different
972 * than given ones. If a family id is present in the family fields of dimensions different
973 * than the given ones, a new family is created and the whole data is updated accordingly.
974 * \param [in] famIds - a sequence of family ids to check.
975 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
976 * famIds should exclusively belong.
977 * \return bool - \c true if no modification is done in \a this mesh by this method.
979 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
981 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
982 std::vector<int> levs=getNonEmptyLevelsExt();
983 std::set<int> levs2(levs.begin(),levs.end());
984 std::vector<int> levsToTest;
985 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
986 std::set<int> famIds2(famIds.begin(),famIds.end());
989 if(!_families.empty())
990 maxFamId=getMaxFamilyId()+1;
991 std::vector<std::string> allFams=getFamiliesNames();
992 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
994 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
997 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
998 std::vector<int> tmp;
999 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1000 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1003 std::string famName=getFamilyNameGivenId(*it2);
1004 std::ostringstream oss; oss << "Family_" << maxFamId;
1005 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1006 addFamilyOnAllGroupsHaving(famName,zeName);
1007 _families[zeName]=maxFamId;
1008 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1017 * Adds a family to a given group in \a this mesh. If the group with a given name does
1018 * not exist, it is created.
1019 * \param [in] grpName - the name of the group to add the family in.
1020 * \param [in] famName - the name of the family to add to the group named \a grpName.
1021 * \throw If \a grpName or \a famName is an empty string.
1022 * \throw If no family named \a famName is present in \a this mesh.
1024 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1026 std::string grpn(grpName);
1027 std::string famn(famName);
1028 if(grpn.empty() || famn.empty())
1029 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1030 std::vector<std::string> fams=getFamiliesNames();
1031 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1033 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1034 oss << "Create this family or choose an existing one ! Existing fams are : ";
1035 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1036 throw INTERP_KERNEL::Exception(oss.str().c_str());
1038 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1039 if(it==_groups.end())
1041 _groups[grpn].push_back(famn);
1045 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1046 if(it2==(*it).second.end())
1047 (*it).second.push_back(famn);
1052 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1053 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1054 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1056 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1058 std::string famNameCpp(famName);
1059 std::string otherCpp(otherFamName);
1060 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1062 std::vector<std::string>& v=(*it).second;
1063 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1065 v.push_back(otherCpp);
1070 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1072 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1075 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1077 std::string fam(familyNameToChange);
1078 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1080 std::vector<std::string>& fams((*it).second);
1081 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1085 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1091 * Returns a name of the family having a given id or, if no such a family exists, creates
1092 * a new uniquely named family and returns its name.
1093 * \param [in] id - the id of the family whose name is required.
1094 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1095 * \return std::string - the name of the existing or the created family.
1096 * \throw If it is not possible to create a unique family name.
1098 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1100 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1104 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1105 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1106 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1107 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1109 * This method will throws an exception if it is not possible to create a unique family name.
1111 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1113 std::vector<std::string> famAlreadyExisting(families.size());
1115 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1117 if((*it).second!=id)
1119 famAlreadyExisting[ii]=(*it).first;
1128 std::ostringstream oss; oss << "Family_" << id;
1129 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1135 * Sets names and ids of all families in \a this mesh.
1136 * \param [in] info - a map of a family name to a family id.
1138 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1144 * Sets names of all groups and families constituting them in \a this mesh.
1145 * \param [in] info - a map of a group name to a vector of names of families
1146 * constituting the group.
1148 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1154 * Returns an id of the family having a given name.
1155 * \param [in] name - the name of the family of interest.
1156 * \return int - the id of the family of interest.
1157 * \throw If no family with such a \a name exists.
1159 int MEDFileMesh::getFamilyId(const std::string& name) const
1161 std::string oname(name);
1162 std::map<std::string, int>::const_iterator it=_families.find(oname);
1163 std::vector<std::string> fams=getFamiliesNames();
1164 if(it==_families.end())
1166 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1167 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1168 throw INTERP_KERNEL::Exception(oss.str().c_str());
1170 return (*it).second;
1174 * Returns ids of the families having given names.
1175 * \param [in] fams - a sequence of the names of families of interest.
1176 * \return std::vector<int> - a sequence of the ids of families of interest.
1177 * \throw If \a fams contains a name of an inexistent family.
1179 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1181 std::vector<int> ret(fams.size());
1183 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1185 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1186 if(it2==_families.end())
1188 std::vector<std::string> fams2=getFamiliesNames();
1189 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1190 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1191 throw INTERP_KERNEL::Exception(oss.str().c_str());
1193 ret[i]=(*it2).second;
1199 * Returns a maximal abs(id) of families in \a this mesh.
1200 * \return int - the maximal norm of family id.
1201 * \throw If there are no families in \a this mesh.
1203 int MEDFileMesh::getMaxAbsFamilyId() const
1205 if(_families.empty())
1206 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1207 int ret=-std::numeric_limits<int>::max();
1208 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1210 ret=std::max(std::abs((*it).second),ret);
1216 * Returns a maximal id of families in \a this mesh.
1217 * \return int - the maximal family id.
1218 * \throw If there are no families in \a this mesh.
1220 int MEDFileMesh::getMaxFamilyId() const
1222 if(_families.empty())
1223 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1224 int ret=-std::numeric_limits<int>::max();
1225 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1227 ret=std::max((*it).second,ret);
1233 * Returns a minimal id of families in \a this mesh.
1234 * \return int - the minimal family id.
1235 * \throw If there are no families in \a this mesh.
1237 int MEDFileMesh::getMinFamilyId() const
1239 if(_families.empty())
1240 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1241 int ret=std::numeric_limits<int>::max();
1242 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1244 ret=std::min((*it).second,ret);
1250 * Returns a maximal id of families in \a this mesh. Not only named families are
1251 * considered but all family fields as well.
1252 * \return int - the maximal family id.
1254 int MEDFileMesh::getTheMaxAbsFamilyId() const
1256 int m1=-std::numeric_limits<int>::max();
1257 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1258 m1=std::max(std::abs((*it).second),m1);
1259 int m2=getMaxAbsFamilyIdInArrays();
1260 return std::max(m1,m2);
1264 * Returns a maximal id of families in \a this mesh. Not only named families are
1265 * considered but all family fields as well.
1266 * \return int - the maximal family id.
1268 int MEDFileMesh::getTheMaxFamilyId() const
1270 int m1=-std::numeric_limits<int>::max();
1271 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1272 m1=std::max((*it).second,m1);
1273 int m2=getMaxFamilyIdInArrays();
1274 return std::max(m1,m2);
1278 * Returns a minimal id of families in \a this mesh. Not only named families are
1279 * considered but all family fields as well.
1280 * \return int - the minimal family id.
1282 int MEDFileMesh::getTheMinFamilyId() const
1284 int m1=std::numeric_limits<int>::max();
1285 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1286 m1=std::min((*it).second,m1);
1287 int m2=getMinFamilyIdInArrays();
1288 return std::min(m1,m2);
1292 * This method only considers the maps. The contain of family array is ignored here.
1294 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1296 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1298 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1300 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1301 v.insert((*it).second);
1302 ret->alloc((int)v.size(),1);
1303 std::copy(v.begin(),v.end(),ret->getPointer());
1308 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1310 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1312 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1314 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1315 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1316 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1318 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1319 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1320 if((DataArrayInt *) ret)
1321 ret=dv->buildUnion(ret);
1329 * true is returned if no modification has been needed. false if family
1330 * renumbering has been needed.
1332 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1334 std::vector<int> levs=getNonEmptyLevelsExt();
1335 std::set<int> allFamIds;
1336 int maxId=getMaxFamilyId()+1;
1337 std::map<int,std::vector<int> > famIdsToRenum;
1338 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1340 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1343 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1345 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1347 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1349 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1352 if(famIdsToRenum.empty())
1354 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1355 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1357 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1358 int *famIdsToChange=fam->getPointer();
1359 std::map<int,int> ren;
1360 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1362 if(allIds->presenceOfValue(*it3))
1364 std::string famName=getFamilyNameGivenId(*it3);
1365 std::vector<std::string> grps=getGroupsOnFamily(famName);
1368 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1369 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1370 addFamilyOnGrp((*it4),newFam);
1373 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1374 for(const int *id=ids->begin();id!=ids->end();id++)
1375 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1381 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1382 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1383 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1384 * This method will throw an exception if a same family id is detected in different level.
1385 * \warning This policy is the opposite of those in MED file documentation ...
1387 void MEDFileMesh::normalizeFamIdsTrio()
1389 ensureDifferentFamIdsPerLevel();
1390 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1391 std::vector<int> levs=getNonEmptyLevelsExt();
1392 std::set<int> levsS(levs.begin(),levs.end());
1393 std::set<std::string> famsFetched;
1394 std::map<std::string,int> families;
1395 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1398 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1402 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1403 std::map<int,int> ren;
1404 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1406 int nbOfTuples=fam->getNumberOfTuples();
1407 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1408 for(int *w=start;w!=start+nbOfTuples;w++)
1410 for(const int *it=tmp->begin();it!=tmp->end();it++)
1412 if(allIds->presenceOfValue(*it))
1414 std::string famName=getFamilyNameGivenId(*it);
1415 families[famName]=ren[*it];
1416 famsFetched.insert(famName);
1421 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1424 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1428 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1429 std::map<int,int> ren;
1430 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1432 int nbOfTuples=fam->getNumberOfTuples();
1433 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1434 for(int *w=start;w!=start+nbOfTuples;w++)
1436 for(const int *it=tmp->begin();it!=tmp->end();it++)
1438 if(allIds->presenceOfValue(*it))
1440 std::string famName=getFamilyNameGivenId(*it);
1441 families[famName]=ren[*it];
1442 famsFetched.insert(famName);
1447 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1449 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1452 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1453 fam->fillWithZero();
1454 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1455 if(allIds->presenceOfValue(*it3))
1457 std::string famName=getFamilyNameGivenId(*it3);
1458 families[famName]=0;
1459 famsFetched.insert(famName);
1464 std::vector<std::string> allFams=getFamiliesNames();
1465 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1466 std::set<std::string> unFetchedIds;
1467 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1468 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1469 families[*it4]=_families[*it4];
1474 * This method normalizes fam id with the following policy.
1475 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1476 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1477 * This method will throw an exception if a same family id is detected in different level.
1479 void MEDFileMesh::normalizeFamIdsMEDFile()
1481 ensureDifferentFamIdsPerLevel();
1482 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1483 std::vector<int> levs=getNonEmptyLevelsExt();
1484 std::set<int> levsS(levs.begin(),levs.end());
1485 std::set<std::string> famsFetched;
1486 std::map<std::string,int> families;
1488 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1491 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1494 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1495 std::map<int,int> ren;
1496 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1498 int nbOfTuples=fam->getNumberOfTuples();
1499 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1500 for(int *w=start;w!=start+nbOfTuples;w++)
1502 for(const int *it=tmp->begin();it!=tmp->end();it++)
1504 if(allIds->presenceOfValue(*it))
1506 std::string famName=getFamilyNameGivenId(*it);
1507 families[famName]=ren[*it];
1508 famsFetched.insert(famName);
1514 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1516 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1519 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1520 std::map<int,int> ren;
1521 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1523 int nbOfTuples=fam->getNumberOfTuples();
1524 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1525 for(int *w=start;w!=start+nbOfTuples;w++)
1527 for(const int *it=tmp->begin();it!=tmp->end();it++)
1529 if(allIds->presenceOfValue(*it))
1531 std::string famName=getFamilyNameGivenId(*it);
1532 families[famName]=ren[*it];
1533 famsFetched.insert(famName);
1539 std::vector<std::string> allFams=getFamiliesNames();
1540 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1541 std::set<std::string> unFetchedIds;
1542 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1543 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1544 families[*it4]=_families[*it4];
1549 * Returns a name of the family by its id. If there are several families having the given
1550 * id, the name first in lexical order is returned.
1551 * \param [in] id - the id of the family whose name is required.
1552 * \return std::string - the name of the found family.
1553 * \throw If no family with the given \a id exists.
1555 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1557 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1558 if((*it).second==id)
1560 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1561 throw INTERP_KERNEL::Exception(oss.str().c_str());
1565 * Returns a string describing \a this mesh. This description includes the mesh name and
1566 * the mesh description string.
1567 * \return std::string - the mesh information string.
1569 std::string MEDFileMesh::simpleRepr() const
1571 std::ostringstream oss;
1572 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1573 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1574 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1579 * Returns ids of mesh entities contained in a given group of a given dimension.
1580 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1582 * \param [in] grp - the name of the group of interest.
1583 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1584 * returned instead of ids.
1585 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1586 * numbers, if available and required, of mesh entities of the group. The caller
1587 * is to delete this array using decrRef() as it is no more needed.
1588 * \throw If the name of a nonexistent group is specified.
1589 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1591 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1593 std::vector<std::string> tmp(1);
1595 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1601 * Returns ids of mesh entities contained in given groups of a given dimension.
1602 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1604 * \param [in] grps - the names of the groups of interest.
1605 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1606 * returned instead of ids.
1607 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1608 * numbers, if available and required, of mesh entities of the groups. The caller
1609 * is to delete this array using decrRef() as it is no more needed.
1610 * \throw If the name of a nonexistent group is present in \a grps.
1611 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1613 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1615 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1616 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1620 * Returns ids of mesh entities contained in a given family of a given dimension.
1621 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1623 * \param [in] fam - the name of the family of interest.
1624 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1625 * returned instead of ids.
1626 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1627 * numbers, if available and required, of mesh entities of the family. The caller
1628 * is to delete this array using decrRef() as it is no more needed.
1629 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1631 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1633 std::vector<std::string> tmp(1);
1635 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1641 * Returns ids of nodes contained in a given group.
1642 * \param [in] grp - the name of the group of interest.
1643 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1644 * returned instead of ids.
1645 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1646 * numbers, if available and required, of nodes of the group. The caller
1647 * is to delete this array using decrRef() as it is no more needed.
1648 * \throw If the name of a nonexistent group is specified.
1649 * \throw If the family field is missing for nodes.
1651 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1653 std::vector<std::string> tmp(1);
1655 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1661 * Returns ids of nodes contained in given groups.
1662 * \param [in] grps - the names of the groups of interest.
1663 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1664 * returned instead of ids.
1665 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1666 * numbers, if available and required, of nodes of the groups. The caller
1667 * is to delete this array using decrRef() as it is no more needed.
1668 * \throw If the name of a nonexistent group is present in \a grps.
1669 * \throw If the family field is missing for nodes.
1671 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1673 return getGroupsArr(1,grps,renum);
1677 * Returns ids of nodes contained in a given group.
1678 * \param [in] grp - the name of the group of interest.
1679 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1680 * returned instead of ids.
1681 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1682 * numbers, if available and required, of nodes of the group. The caller
1683 * is to delete this array using decrRef() as it is no more needed.
1684 * \throw If the name of a nonexistent group is specified.
1685 * \throw If the family field is missing for nodes.
1687 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1689 std::vector<std::string> tmp(1);
1691 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1697 * Returns ids of nodes contained in given families.
1698 * \param [in] fams - the names of the families of interest.
1699 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1700 * returned instead of ids.
1701 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1702 * numbers, if available and required, of nodes of the families. The caller
1703 * is to delete this array using decrRef() as it is no more needed.
1704 * \throw If the family field is missing for nodes.
1706 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1708 return getFamiliesArr(1,fams,renum);
1712 * Adds groups of given dimension and creates corresponding families and family fields
1713 * given ids of mesh entities of each group.
1714 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1715 * \param [in] grps - a sequence of arrays of ids each describing a group.
1716 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1718 * \throw If names of some groups in \a grps are equal.
1719 * \throw If \a grps includes a group with an empty name.
1720 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1721 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1723 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1727 std::set<std::string> grpsName;
1728 std::vector<std::string> grpsName2(grps.size());
1731 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1733 grpsName.insert((*it)->getName());
1734 grpsName2[i]=(*it)->getName();
1736 if(grpsName.size()!=grps.size())
1737 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1738 if(grpsName.find(std::string(""))!=grpsName.end())
1739 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1740 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1741 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1742 std::vector< std::vector<int> > fidsOfGroups;
1745 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1749 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1750 for(unsigned int ii=0;ii<grps.size();ii++)
1752 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1753 grps2[ii]->setName(grps[ii]->getName());
1755 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1756 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1759 if(!_families.empty())
1760 offset=getMaxAbsFamilyId()+1;
1761 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1762 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1763 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1764 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1768 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1769 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1770 * For the moment, the two last input parameters are not taken into account.
1772 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1774 std::map<int,std::string> famInv;
1775 for(const int *it=famIds->begin();it!=famIds->end();it++)
1777 std::ostringstream oss;
1778 oss << "Family_" << (*it);
1779 _families[oss.str()]=(*it);
1780 famInv[*it]=oss.str();
1783 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1785 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1787 _groups[grpNames[i]].push_back(famInv[*it2]);
1792 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1794 std::vector<int> levs(getNonEmptyLevels());
1795 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1796 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1798 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1799 ret.insert(ret.end(),elts.begin(),elts.end());
1804 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1806 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1807 return mLev->getDistributionOfTypes();
1810 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1812 famArr->applyLin(offset>0?1:-1,offset,0);
1813 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1816 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1817 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1822 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1823 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1824 * If this method fails to find such a name it will throw an exception.
1826 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1829 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1832 std::size_t len=nameTry.length();
1833 for(std::size_t ii=1;ii<len;ii++)
1835 std::string tmp=nameTry.substr(ii,len-ii);
1836 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1842 for(std::size_t i=1;i<30;i++)
1844 std::string tmp1(nameTry.at(0),i);
1846 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1852 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1854 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1856 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1859 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
1861 std::size_t nbOfChunks=code.size()/3;
1862 if(code.size()%3!=0)
1863 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1865 for(std::size_t i=0;i<nbOfChunks;i++)
1874 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1875 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1876 * If _name is not empty and that 'm' has the same name nothing is done.
1877 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1879 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
1882 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1887 std::string name(m->getName());
1892 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1893 oss << name << "' ! Names must match !";
1894 throw INTERP_KERNEL::Exception(oss.str().c_str());
1898 if(_desc_name.empty())
1899 _desc_name=m->getDescription();
1902 std::string name(m->getDescription());
1905 if(_desc_name!=name)
1907 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1908 oss << name << "' ! Names must match !";
1909 throw INTERP_KERNEL::Exception(oss.str().c_str());
1915 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1917 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1918 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1920 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1921 oss << " - Groups lying on this family : ";
1922 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
1923 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1924 oss << std::endl << std::endl;
1929 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1930 * file. The mesh to load is specified by its name and numbers of a time step and an
1932 * \param [in] fileName - the name of MED file to read.
1933 * \param [in] mName - the name of the mesh to read.
1934 * \param [in] dt - the number of a time step.
1935 * \param [in] it - the number of an iteration.
1936 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1937 * mesh using decrRef() as it is no more needed.
1938 * \throw If the file is not readable.
1939 * \throw If there is no mesh with given attributes in the file.
1940 * \throw If the mesh in the file is not an unstructured one.
1942 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
1944 MEDFileUtilities::CheckFileForRead(fileName);
1945 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1946 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1950 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1951 * file. The first mesh in the file is loaded.
1952 * \param [in] fileName - the name of MED file to read.
1953 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1954 * mesh using decrRef() as it is no more needed.
1955 * \throw If the file is not readable.
1956 * \throw If there is no meshes in the file.
1957 * \throw If the mesh in the file is not an unstructured one.
1959 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
1961 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1964 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1965 throw INTERP_KERNEL::Exception(oss.str().c_str());
1967 MEDFileUtilities::CheckFileForRead(fileName);
1968 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1970 ParaMEDMEM::MEDCouplingMeshType meshType;
1972 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
1973 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
1977 * Returns an empty instance of MEDFileUMesh.
1978 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1979 * mesh using decrRef() as it is no more needed.
1981 MEDFileUMesh *MEDFileUMesh::New()
1983 return new MEDFileUMesh;
1986 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
1988 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
1989 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1993 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
1995 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
1996 ret.push_back((const DataArrayDouble*)_coords);
1997 ret.push_back((const DataArrayInt *)_fam_coords);
1998 ret.push_back((const DataArrayInt *)_num_coords);
1999 ret.push_back((const DataArrayInt *)_rev_num_coords);
2000 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2001 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2002 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2006 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2008 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2012 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2014 return new MEDFileUMesh;
2017 MEDFileMesh *MEDFileUMesh::deepCpy() const
2019 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2020 if((const DataArrayDouble*)_coords)
2021 ret->_coords=_coords->deepCpy();
2022 if((const DataArrayInt*)_fam_coords)
2023 ret->_fam_coords=_fam_coords->deepCpy();
2024 if((const DataArrayInt*)_num_coords)
2025 ret->_num_coords=_num_coords->deepCpy();
2026 if((const DataArrayInt*)_rev_num_coords)
2027 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2028 if((const DataArrayAsciiChar*)_name_coords)
2029 ret->_name_coords=_name_coords->deepCpy();
2031 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2033 if((const MEDFileUMeshSplitL1 *)(*it))
2034 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2040 * Checks if \a this and another mesh are equal.
2041 * \param [in] other - the mesh to compare with.
2042 * \param [in] eps - a precision used to compare real values.
2043 * \param [in,out] what - the string returning description of unequal data.
2044 * \return bool - \c true if the meshes are equal, \c false, else.
2046 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2048 if(!MEDFileMesh::isEqual(other,eps,what))
2050 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2053 what="Mesh types differ ! This is unstructured and other is NOT !";
2056 clearNonDiscrAttributes();
2057 otherC->clearNonDiscrAttributes();
2058 const DataArrayDouble *coo1=_coords;
2059 const DataArrayDouble *coo2=otherC->_coords;
2060 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2062 what="Mismatch of coordinates ! One is defined and not other !";
2067 bool ret=coo1->isEqual(*coo2,eps);
2070 what="Coords differ !";
2074 const DataArrayInt *famc1=_fam_coords;
2075 const DataArrayInt *famc2=otherC->_fam_coords;
2076 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2078 what="Mismatch of families arr on nodes ! One is defined and not other !";
2083 bool ret=famc1->isEqual(*famc2);
2086 what="Families arr on node differ !";
2090 const DataArrayInt *numc1=_num_coords;
2091 const DataArrayInt *numc2=otherC->_num_coords;
2092 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2094 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2099 bool ret=numc1->isEqual(*numc2);
2102 what="Numbering arr on node differ !";
2106 const DataArrayAsciiChar *namec1=_name_coords;
2107 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2108 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2110 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2115 bool ret=namec1->isEqual(*namec2);
2118 what="Names arr on node differ !";
2122 if(_ms.size()!=otherC->_ms.size())
2124 what="Number of levels differs !";
2127 std::size_t sz=_ms.size();
2128 for(std::size_t i=0;i<sz;i++)
2130 const MEDFileUMeshSplitL1 *s1=_ms[i];
2131 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2132 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2134 what="Mismatch of presence of sub levels !";
2139 bool ret=s1->isEqual(s2,eps,what);
2148 * Clears redundant attributes of incorporated data arrays.
2150 void MEDFileUMesh::clearNonDiscrAttributes() const
2152 MEDFileMesh::clearNonDiscrAttributes();
2153 const DataArrayDouble *coo1=_coords;
2155 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2156 const DataArrayInt *famc1=_fam_coords;
2158 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2159 const DataArrayInt *numc1=_num_coords;
2161 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2162 const DataArrayAsciiChar *namc1=_name_coords;
2164 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2165 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2167 const MEDFileUMeshSplitL1 *tmp=(*it);
2169 tmp->clearNonDiscrAttributes();
2173 void MEDFileUMesh::setName(const std::string& name)
2175 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2176 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2177 (*it)->setName(name);
2178 MEDFileMesh::setName(name);
2181 MEDFileUMesh::MEDFileUMesh()
2185 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2188 loadUMeshFromFile(fid,mName,dt,it,mrs);
2190 catch(INTERP_KERNEL::Exception& e)
2195 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2197 MEDFileUMeshL2 loaderl2;
2198 ParaMEDMEM::MEDCouplingMeshType meshType;
2201 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2202 if(meshType!=UNSTRUCTURED)
2204 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2205 throw INTERP_KERNEL::Exception(oss.str().c_str());
2207 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2208 int lev=loaderl2.getNumberOfLevels();
2210 for(int i=0;i<lev;i++)
2212 if(!loaderl2.emptyLev(i))
2213 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2217 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2219 setName(loaderl2.getName());
2220 setDescription(loaderl2.getDescription());
2221 setUnivName(loaderl2.getUnivName());
2222 setIteration(loaderl2.getIteration());
2223 setOrder(loaderl2.getOrder());
2224 setTimeValue(loaderl2.getTime());
2225 setTimeUnit(loaderl2.getTimeUnit());
2226 _coords=loaderl2.getCoords();
2227 if(!mrs || mrs->isNodeFamilyFieldReading())
2228 _fam_coords=loaderl2.getCoordsFamily();
2229 if(!mrs || mrs->isNodeNumFieldReading())
2230 _num_coords=loaderl2.getCoordsNum();
2231 if(!mrs || mrs->isNodeNameFieldReading())
2232 _name_coords=loaderl2.getCoordsName();
2236 MEDFileUMesh::~MEDFileUMesh()
2240 void MEDFileUMesh::writeLL(med_idt fid) const
2242 const DataArrayDouble *coo=_coords;
2243 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2244 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2245 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2246 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2247 int spaceDim=coo?coo->getNumberOfComponents():0;
2248 int mdim=getMeshDimension();
2249 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2250 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2251 for(int i=0;i<spaceDim;i++)
2253 std::string info=coo->getInfoOnComponent(i);
2255 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2256 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
2257 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
2259 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2260 MEDmeshUniversalNameWr(fid,maa);
2261 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2262 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2263 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2264 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2265 (*it)->write(fid,meshName,mdim);
2266 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2270 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2271 * \return std::vector<int> - a sequence of the relative dimensions.
2273 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2275 std::vector<int> ret;
2277 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2278 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2285 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2286 * \return std::vector<int> - a sequence of the relative dimensions.
2288 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2290 std::vector<int> ret0=getNonEmptyLevels();
2291 if((const DataArrayDouble *) _coords)
2293 std::vector<int> ret(ret0.size()+1);
2295 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2301 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2303 std::vector<int> ret;
2304 const DataArrayInt *famCoo(_fam_coords);
2308 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2310 const MEDFileUMeshSplitL1 *cur(*it);
2312 if(cur->getFamilyField())
2318 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2320 std::vector<int> ret;
2321 const DataArrayInt *numCoo(_num_coords);
2325 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2327 const MEDFileUMeshSplitL1 *cur(*it);
2329 if(cur->getNumberField())
2335 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2337 std::vector<int> ret;
2338 const DataArrayAsciiChar *nameCoo(_name_coords);
2342 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2344 const MEDFileUMeshSplitL1 *cur(*it);
2346 if(cur->getNameField())
2353 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2354 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2355 * \param [in] grp - the name of the group of interest.
2356 * \return std::vector<int> - a sequence of the relative dimensions.
2358 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2360 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2361 return getFamsNonEmptyLevels(fams);
2365 * Returns all relative mesh levels (including nodes) where a given group is defined.
2366 * \param [in] grp - the name of the group of interest.
2367 * \return std::vector<int> - a sequence of the relative dimensions.
2369 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2371 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2372 return getFamsNonEmptyLevelsExt(fams);
2376 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2377 * To include nodes, call getFamNonEmptyLevelsExt() method.
2378 * \param [in] fam - the name of the family of interest.
2379 * \return std::vector<int> - a sequence of the relative dimensions.
2381 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2383 std::vector<std::string> fams(1,std::string(fam));
2384 return getFamsNonEmptyLevels(fams);
2388 * Returns all relative mesh levels (including nodes) where a given family is defined.
2389 * \param [in] fam - the name of the family of interest.
2390 * \return std::vector<int> - a sequence of the relative dimensions.
2392 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2394 std::vector<std::string> fams(1,std::string(fam));
2395 return getFamsNonEmptyLevelsExt(fams);
2399 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2400 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2401 * \param [in] grps - a sequence of names of the groups of interest.
2402 * \return std::vector<int> - a sequence of the relative dimensions.
2404 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2406 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2407 return getFamsNonEmptyLevels(fams);
2411 * Returns all relative mesh levels (including nodes) where given groups are defined.
2412 * \param [in] grps - a sequence of names of the groups of interest.
2413 * \return std::vector<int> - a sequence of the relative dimensions.
2415 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2417 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2418 return getFamsNonEmptyLevelsExt(fams);
2422 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2423 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2424 * \param [in] fams - the name of the family of interest.
2425 * \return std::vector<int> - a sequence of the relative dimensions.
2427 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2429 std::vector<int> ret;
2430 std::vector<int> levs=getNonEmptyLevels();
2431 std::vector<int> famIds=getFamiliesIds(fams);
2432 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2433 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2439 * Returns all relative mesh levels (including nodes) where given families are defined.
2440 * \param [in] fams - the names of the families of interest.
2441 * \return std::vector<int> - a sequence of the relative dimensions.
2443 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2445 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2446 const DataArrayInt *famCoords=_fam_coords;
2449 std::vector<int> famIds=getFamiliesIds(fams);
2450 if(famCoords->presenceOfValue(famIds))
2452 std::vector<int> ret(ret0.size()+1);
2454 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2462 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2463 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2464 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2467 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2469 std::vector<std::string> ret;
2470 std::vector<std::string> allGrps=getGroupsNames();
2471 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2473 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2474 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2480 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2482 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2483 if((const DataArrayInt *)_fam_coords)
2485 int val=_fam_coords->getMaxValue(tmp);
2486 ret=std::max(ret,std::abs(val));
2488 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2490 if((const MEDFileUMeshSplitL1 *)(*it))
2492 const DataArrayInt *da=(*it)->getFamilyField();
2495 int val=da->getMaxValue(tmp);
2496 ret=std::max(ret,std::abs(val));
2503 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2505 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2506 if((const DataArrayInt *)_fam_coords)
2508 int val=_fam_coords->getMaxValue(tmp);
2509 ret=std::max(ret,val);
2511 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2513 if((const MEDFileUMeshSplitL1 *)(*it))
2515 const DataArrayInt *da=(*it)->getFamilyField();
2518 int val=da->getMaxValue(tmp);
2519 ret=std::max(ret,val);
2526 int MEDFileUMesh::getMinFamilyIdInArrays() const
2528 int ret=std::numeric_limits<int>::max(),tmp=-1;
2529 if((const DataArrayInt *)_fam_coords)
2531 int val=_fam_coords->getMinValue(tmp);
2532 ret=std::min(ret,val);
2534 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2536 if((const MEDFileUMeshSplitL1 *)(*it))
2538 const DataArrayInt *da=(*it)->getFamilyField();
2541 int val=da->getMinValue(tmp);
2542 ret=std::min(ret,val);
2550 * Returns the dimension on cells in \a this mesh.
2551 * \return int - the mesh dimension.
2552 * \throw If there are no cells in this mesh.
2554 int MEDFileUMesh::getMeshDimension() const
2557 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2558 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2559 return (*it)->getMeshDimension()+lev;
2560 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2564 * Returns the space dimension of \a this mesh that is equal to number of components in
2565 * the node coordinates array.
2566 * \return int - the space dimension of \a this mesh.
2567 * \throw If the node coordinates array is not available.
2569 int MEDFileUMesh::getSpaceDimension() const
2571 const DataArrayDouble *coo=_coords;
2573 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2574 return coo->getNumberOfComponents();
2578 * Returns a string describing \a this mesh.
2579 * \return std::string - the mesh information string.
2581 std::string MEDFileUMesh::simpleRepr() const
2583 std::ostringstream oss;
2584 oss << MEDFileMesh::simpleRepr();
2585 const DataArrayDouble *coo=_coords;
2586 oss << "- The dimension of the space is ";
2587 static const char MSG1[]= "*** NO COORDS SET ***";
2588 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2590 oss << _coords->getNumberOfComponents() << std::endl;
2592 oss << MSG1 << std::endl;
2593 oss << "- Type of the mesh : UNSTRUCTURED\n";
2594 oss << "- Number of nodes : ";
2596 oss << _coords->getNumberOfTuples() << std::endl;
2598 oss << MSG1 << std::endl;
2599 std::size_t nbOfLev=_ms.size();
2600 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2601 for(std::size_t i=0;i<nbOfLev;i++)
2603 const MEDFileUMeshSplitL1 *lev=_ms[i];
2604 oss << " - Level #" << -((int) i) << " has dimension : ";
2607 oss << lev->getMeshDimension() << std::endl;
2608 lev->simpleRepr(oss);
2611 oss << MSG2 << std::endl;
2613 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2616 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2617 oss << "- Names of coordinates :" << std::endl;
2618 std::vector<std::string> vars=coo->getVarsOnComponent();
2619 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2620 oss << std::endl << "- Units of coordinates : " << std::endl;
2621 std::vector<std::string> units=coo->getUnitsOnComponent();
2622 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2624 oss << std::endl << std::endl;
2630 * Returns a full textual description of \a this mesh.
2631 * \return std::string - the string holding the mesh description.
2633 std::string MEDFileUMesh::advancedRepr() const
2635 return simpleRepr();
2639 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2640 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2641 * \return int - the number of entities.
2642 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2644 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2646 if(meshDimRelToMaxExt==1)
2648 if(!((const DataArrayDouble *)_coords))
2649 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2650 return _coords->getNumberOfTuples();
2652 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2656 * Returns the family field for mesh entities of a given dimension.
2657 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2658 * \return const DataArrayInt * - the family field. It is an array of ids of families
2659 * each mesh entity belongs to. It can be \c NULL.
2661 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2663 if(meshDimRelToMaxExt==1)
2665 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2666 return l1->getFamilyField();
2670 * Returns the optional numbers of mesh entities of a given dimension.
2671 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2672 * \return const DataArrayInt * - the array of the entity numbers.
2673 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2675 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2677 if(meshDimRelToMaxExt==1)
2679 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2680 return l1->getNumberField();
2683 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2685 if(meshDimRelToMaxExt==1)
2686 return _name_coords;
2687 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2688 return l1->getNameField();
2691 int MEDFileUMesh::getNumberOfNodes() const
2693 const DataArrayDouble *coo=_coords;
2695 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2696 return coo->getNumberOfTuples();
2699 bool MEDFileUMesh::hasImplicitPart() const
2704 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
2706 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
2709 void MEDFileUMesh::releaseImplicitPartIfAny() const
2713 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2715 std::size_t sz(st.getNumberOfItems());
2716 for(std::size_t i=0;i<sz;i++)
2718 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2719 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2720 if(st[i].getPflName().empty())
2721 m->computeNodeIdsAlg(nodesFetched);
2724 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2725 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2726 m2->computeNodeIdsAlg(nodesFetched);
2732 * Returns the optional numbers of mesh entities of a given dimension transformed using
2733 * DataArrayInt::invertArrayN2O2O2N().
2734 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2735 * \return const DataArrayInt * - the array of the entity numbers transformed using
2736 * DataArrayInt::invertArrayN2O2O2N().
2737 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2739 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2741 if(meshDimRelToMaxExt==1)
2743 if(!((const DataArrayInt *)_num_coords))
2744 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2745 return _rev_num_coords;
2747 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2748 return l1->getRevNumberField();
2752 * Returns a pointer to the node coordinates array of \a this mesh \b without
2753 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2755 DataArrayDouble *MEDFileUMesh::getCoords() const
2757 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2758 if((DataArrayDouble *)tmp)
2766 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2767 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2769 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2770 * \param [in] grp - the name of the group whose mesh entities are included in the
2772 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2773 * according to the optional numbers of entities, if available.
2774 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2775 * delete this mesh using decrRef() as it is no more needed.
2776 * \throw If the name of a nonexistent group is specified.
2777 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2779 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2781 synchronizeTinyInfoOnLeaves();
2782 std::vector<std::string> tmp(1);
2784 return getGroups(meshDimRelToMaxExt,tmp,renum);
2788 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2789 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2791 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2792 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2794 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2795 * according to the optional numbers of entities, if available.
2796 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2797 * delete this mesh using decrRef() as it is no more needed.
2798 * \throw If a name of a nonexistent group is present in \a grps.
2799 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2801 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2803 synchronizeTinyInfoOnLeaves();
2804 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2805 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2806 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2807 zeRet->setName(grps[0]);
2808 return zeRet.retn();
2812 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2813 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2815 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2816 * \param [in] fam - the name of the family whose mesh entities are included in the
2818 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2819 * according to the optional numbers of entities, if available.
2820 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2821 * delete this mesh using decrRef() as it is no more needed.
2822 * \throw If a name of a nonexistent family is present in \a grps.
2823 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2825 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2827 synchronizeTinyInfoOnLeaves();
2828 std::vector<std::string> tmp(1);
2830 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2834 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2835 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2837 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2838 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2840 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2841 * according to the optional numbers of entities, if available.
2842 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2843 * delete this mesh using decrRef() as it is no more needed.
2844 * \throw If a name of a nonexistent family is present in \a fams.
2845 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2847 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2849 synchronizeTinyInfoOnLeaves();
2850 if(meshDimRelToMaxExt==1)
2852 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2853 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2854 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2858 std::vector<int> famIds=getFamiliesIds(fams);
2859 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2860 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2862 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2864 zeRet=l1->getFamilyPart(0,0,renum);
2865 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2866 zeRet->setName(fams[0]);
2867 return zeRet.retn();
2871 * Returns ids of mesh entities contained in given families of a given dimension.
2872 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2874 * \param [in] fams - the names of the families of interest.
2875 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2876 * returned instead of ids.
2877 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2878 * numbers, if available and required, of mesh entities of the families. The caller
2879 * is to delete this array using decrRef() as it is no more needed.
2880 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2882 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2884 std::vector<int> famIds=getFamiliesIds(fams);
2885 if(meshDimRelToMaxExt==1)
2887 if((const DataArrayInt *)_fam_coords)
2889 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2891 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2893 da=_fam_coords->getIdsEqualList(0,0);
2895 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2900 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2902 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2904 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2906 return l1->getFamilyPartArr(0,0,renum);
2910 * Returns a MEDCouplingUMesh of a given relative dimension.
2911 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2912 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2913 * To build a valid MEDCouplingUMesh from the returned one in this case,
2914 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2915 * \param [in] meshDimRelToMax - the relative dimension of interest.
2916 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2917 * optional numbers of mesh entities.
2918 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2919 * delete using decrRef() as it is no more needed.
2920 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2921 * \sa getGenMeshAtLevel()
2923 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
2925 synchronizeTinyInfoOnLeaves();
2926 if(meshDimRelToMaxExt==1)
2930 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2931 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2932 umesh->setCoords(cc);
2933 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2934 umesh->setName(getName());
2938 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2939 return l1->getWholeMesh(renum);
2943 * Returns a MEDCouplingUMesh of a given relative dimension.
2944 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2945 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2946 * To build a valid MEDCouplingUMesh from the returned one in this case,
2947 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2948 * \param [in] meshDimRelToMax - the relative dimension of interest.
2949 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2950 * optional numbers of mesh entities.
2951 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2952 * delete using decrRef() as it is no more needed.
2953 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2954 * \sa getMeshAtLevel()
2956 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
2958 return getMeshAtLevel(meshDimRelToMax,renum);
2961 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
2963 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
2964 return l1->getDistributionOfTypes();
2968 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2969 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2970 * optional numbers of mesh entities.
2971 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2972 * delete using decrRef() as it is no more needed.
2973 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2975 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
2977 return getMeshAtLevel(0,renum);
2981 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2982 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2983 * optional numbers of mesh entities.
2984 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2985 * delete using decrRef() as it is no more needed.
2986 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2988 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
2990 return getMeshAtLevel(-1,renum);
2994 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2995 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2996 * optional numbers of mesh entities.
2997 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2998 * delete using decrRef() as it is no more needed.
2999 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3001 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3003 return getMeshAtLevel(-2,renum);
3007 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3008 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3009 * optional numbers of mesh entities.
3010 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3011 * delete using decrRef() as it is no more needed.
3012 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3014 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3016 return getMeshAtLevel(-3,renum);
3020 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3021 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3022 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3023 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3025 void MEDFileUMesh::forceComputationOfParts() const
3027 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3029 const MEDFileUMeshSplitL1 *elt(*it);
3031 elt->forceComputationOfParts();
3036 * This method returns a vector of mesh parts containing each exactly one geometric type.
3037 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3038 * This method is only for memory aware users.
3039 * The returned pointers are **NOT** new object pointer. No need to mange them.
3041 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3043 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3044 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3048 * This method returns the part of \a this having the geometric type \a gt.
3049 * If such part is not existing an exception will be thrown.
3050 * The returned pointer is **NOT** new object pointer. No need to mange it.
3052 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3054 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3055 int lev=(int)cm.getDimension()-getMeshDimension();
3056 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3057 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3061 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3062 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3064 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3066 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3067 return sp->getGeoTypes();
3071 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3072 * \param [in] gt - the geometric type for which the family field is asked.
3073 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3074 * delete using decrRef() as it is no more needed.
3075 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3077 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3079 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3080 int lev=(int)cm.getDimension()-getMeshDimension();
3081 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3082 return sp->extractFamilyFieldOnGeoType(gt);
3086 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3087 * \param [in] gt - the geometric type for which the number field is asked.
3088 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3089 * delete using decrRef() as it is no more needed.
3090 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3092 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3094 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3095 int lev=(int)cm.getDimension()-getMeshDimension();
3096 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3097 return sp->extractNumberFieldOnGeoType(gt);
3100 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3102 if(meshDimRelToMaxExt==1)
3103 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3104 if(meshDimRelToMaxExt>1)
3105 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3106 int tracucedRk=-meshDimRelToMaxExt;
3107 if(tracucedRk>=(int)_ms.size())
3108 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3109 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3110 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3111 return _ms[tracucedRk];
3114 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3116 if(meshDimRelToMaxExt==1)
3117 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3118 if(meshDimRelToMaxExt>1)
3119 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3120 int tracucedRk=-meshDimRelToMaxExt;
3121 if(tracucedRk>=(int)_ms.size())
3122 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3123 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3124 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3125 return _ms[tracucedRk];
3128 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3130 if(-meshDimRelToMax>=(int)_ms.size())
3131 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3133 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3135 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3137 int ref=(*it)->getMeshDimension();
3138 if(ref+i!=meshDim-meshDimRelToMax)
3139 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3145 * Sets the node coordinates array of \a this mesh.
3146 * \param [in] coords - the new node coordinates array.
3147 * \throw If \a coords == \c NULL.
3149 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3152 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3153 coords->checkAllocated();
3154 int nbOfTuples=coords->getNumberOfTuples();
3157 _fam_coords=DataArrayInt::New();
3158 _fam_coords->alloc(nbOfTuples,1);
3159 _fam_coords->fillWithZero();
3160 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3161 if((MEDFileUMeshSplitL1 *)(*it))
3162 (*it)->setCoords(coords);
3166 * Removes all groups of a given dimension in \a this mesh.
3167 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3168 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3170 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3172 if(meshDimRelToMaxExt==1)
3174 if((DataArrayInt *)_fam_coords)
3175 _fam_coords->fillWithZero();
3178 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3179 l1->eraseFamilyField();
3184 * Removes all families with ids not present in the family fields of \a this mesh.
3186 void MEDFileUMesh::optimizeFamilies()
3188 std::vector<int> levs=getNonEmptyLevelsExt();
3189 std::set<int> allFamsIds;
3190 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3192 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3193 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3195 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3198 std::set<std::string> famNamesToKill;
3199 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3201 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3202 famNamesToKill.insert((*it).first);
3204 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3205 _families.erase(*it);
3206 std::vector<std::string> grpNamesToKill;
3207 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3209 std::vector<std::string> tmp;
3210 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3212 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3213 tmp.push_back(*it2);
3218 tmp.push_back((*it).first);
3220 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3224 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3226 std::vector<int> levs=getNonEmptyLevels();
3227 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3228 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3229 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3230 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3231 int nbNodes=m0->getNumberOfNodes();
3232 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3233 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3234 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3235 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3236 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3237 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3238 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3239 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3240 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3241 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3242 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3243 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3244 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3245 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3246 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3247 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3248 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3249 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3250 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3251 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3252 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3253 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3254 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3255 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3256 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3257 m0->setCoords(tmp0->getCoords());
3258 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3259 m1->setCoords(m0->getCoords());
3260 _coords=m0->getCoords(); _coords->incrRef();
3261 // duplication of cells in group 'grpNameM1' on level -1
3262 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3263 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3264 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3265 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3266 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3268 newm1->setName(getName());
3269 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3271 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3272 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3273 newFam->alloc(newm1->getNumberOfCells(),1);
3274 int idd=getMaxFamilyId()+1;
3275 int globStart=0,start=0,end,globEnd;
3276 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3277 for(int i=0;i<nbOfChunks;i++)
3279 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3280 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3282 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3283 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3284 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3289 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3293 newm1->setCoords(getCoords());
3294 setMeshAtLevel(-1,newm1);
3295 setFamilyFieldArr(-1,newFam);
3296 std::string grpName2(grpNameM1); grpName2+="_dup";
3297 addFamily(grpName2,idd);
3298 addFamilyOnGrp(grpName2,grpName2);
3303 int newNbOfNodes=getCoords()->getNumberOfTuples();
3304 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3305 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3306 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3309 nodesDuplicated=nodeIdsToDuplicate.retn();
3310 cellsModified=cellsToModifyConn0.retn();
3311 cellsNotModified=cellsToModifyConn1.retn();
3315 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3316 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3317 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3319 * \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.
3320 * 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.
3322 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3324 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3325 std::vector<int> levs=getNonEmptyLevels();
3327 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3328 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3331 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3333 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3334 std::vector<int> code1=m->getDistributionOfTypes();
3335 end=PutInThirdComponentOfCodeOffset(code1,start);
3336 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3337 bool hasChanged=m->unPolyze();
3338 DataArrayInt *fake=0;
3339 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3340 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3342 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3345 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3346 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3348 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3349 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3350 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3351 setMeshAtLevel(*it,m);
3352 std::vector<int> code2=m->getDistributionOfTypes();
3353 end=PutInThirdComponentOfCodeOffset(code2,start);
3354 newCode.insert(newCode.end(),code2.begin(),code2.end());
3356 if(o2nCellsPart2->isIdentity())
3360 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3361 setFamilyFieldArr(*it,newFamField);
3365 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3366 setRenumFieldArr(*it,newNumField);
3371 newCode.insert(newCode.end(),code1.begin(),code1.end());
3377 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3378 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3379 o2nRenumCell=o2nRenumCellRet.retn();
3384 struct MEDLoaderAccVisit1
3386 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3387 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3388 int _new_nb_of_nodes;
3392 * 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.
3393 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3394 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3395 * -1 values in returned array means that the corresponding old node is no more used.
3397 * \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
3398 * is modified in \a this.
3399 * \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
3402 DataArrayInt *MEDFileUMesh::zipCoords()
3404 const DataArrayDouble *coo=getCoords();
3406 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3407 int nbOfNodes=coo->getNumberOfTuples();
3408 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3409 std::vector<int> neLevs=getNonEmptyLevels();
3410 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3412 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3413 m->computeNodeIdsAlg(nodeIdsInUse);
3415 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3416 if(nbrOfNodesInUse==nbOfNodes)
3418 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3419 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3420 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3421 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3422 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3423 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3424 if((const DataArrayInt *)_fam_coords)
3425 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3426 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3427 if((const DataArrayInt *)_num_coords)
3428 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3429 if((const DataArrayAsciiChar *)_name_coords)
3430 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3431 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3432 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3434 if((MEDFileUMeshSplitL1*)*it)
3435 (*it)->renumberNodesInConn(ret->begin());
3441 * Adds a group of nodes to \a this mesh.
3442 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3443 * The ids should be sorted and different each other (MED file norm).
3444 * \throw If the node coordinates array is not set.
3445 * \throw If \a ids == \c NULL.
3446 * \throw If \a ids->getName() == "".
3447 * \throw If \a ids does not respect the MED file norm.
3448 * \throw If a group with name \a ids->getName() already exists.
3450 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
3452 const DataArrayDouble *coords=_coords;
3454 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3455 int nbOfNodes=coords->getNumberOfTuples();
3456 if(!((DataArrayInt *)_fam_coords))
3457 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3459 addGroupUnderground(true,ids,_fam_coords);
3463 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3464 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3465 * The ids should be sorted and different each other (MED file norm).
3466 * \throw If the node coordinates array is not set.
3467 * \throw If \a ids == \c NULL.
3468 * \throw If \a ids->getName() == "".
3469 * \throw If \a ids does not respect the MED file norm.
3470 * \throw If a group with name \a ids->getName() already exists.
3472 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
3474 std::vector<int> levs=getNonEmptyLevelsExt();
3475 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3477 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3478 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3480 if(meshDimRelToMaxExt==1)
3481 { addNodeGroup(ids); return ; }
3482 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3483 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3484 addGroupUnderground(false,ids,fam);
3488 * \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).
3489 * \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)
3491 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
3494 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3495 std::string grpName(ids->getName());
3497 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3498 ids->checkStrictlyMonotonic(true);
3499 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3500 std::vector<std::string> grpsNames=getGroupsNames();
3501 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3503 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3504 throw INTERP_KERNEL::Exception(oss.str().c_str());
3506 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3507 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3508 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3509 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3510 std::vector<int> familyIds;
3511 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3512 int maxVal=getTheMaxAbsFamilyId()+1;
3513 std::map<std::string,int> families(_families);
3514 std::map<std::string, std::vector<std::string> > groups(_groups);
3515 std::vector<std::string> fams;
3516 bool created(false);
3517 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3519 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3520 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3521 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3522 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3525 bool isFamPresent=false;
3526 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3527 isFamPresent=(*itl)->presenceOfValue(*famId);
3529 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3532 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3533 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3534 fams.push_back(locFamName);
3535 if(existsFamily(*famId))
3537 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3538 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3541 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3545 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3546 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3547 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3548 if(existsFamily(*famId))
3550 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3551 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3556 for(std::size_t i=0;i<familyIds.size();i++)
3558 DataArrayInt *da=idsPerfamiliyIds[i];
3559 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3563 _groups[grpName]=fams;
3567 * Changes a name of a family specified by its id.
3568 * \param [in] id - the id of the family of interest.
3569 * \param [in] newFamName - the new family name.
3570 * \throw If no family with the given \a id exists.
3572 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
3574 std::string oldName=getFamilyNameGivenId(id);
3575 _families.erase(oldName);
3576 _families[newFamName]=id;
3580 * Removes a mesh of a given dimension.
3581 * \param [in] meshDimRelToMax - the relative dimension of interest.
3582 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3584 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
3586 std::vector<int> levSet=getNonEmptyLevels();
3587 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3588 if(it==levSet.end())
3589 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3590 int pos=(-meshDimRelToMax);
3595 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
3596 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3597 * \param [in] m - the new mesh to set.
3598 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3600 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3601 * another node coordinates array.
3602 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3603 * to the existing meshes of other levels of \a this mesh.
3605 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
3607 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
3608 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3612 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3613 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3614 * \param [in] m - the new mesh to set.
3615 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3616 * writing \a this mesh in a MED file.
3617 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3619 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3620 * another node coordinates array.
3621 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3622 * to the existing meshes of other levels of \a this mesh.
3624 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
3626 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
3627 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3630 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
3632 dealWithTinyInfo(m);
3633 std::vector<int> levSet=getNonEmptyLevels();
3634 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3636 if((DataArrayDouble *)_coords==0)
3638 DataArrayDouble *c=m->getCoords();
3643 if(m->getCoords()!=_coords)
3644 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3645 int sz=(-meshDimRelToMax)+1;
3646 if(sz>=(int)_ms.size())
3648 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3652 return _ms[-meshDimRelToMax];
3656 * This method allows to set at once the content of different levels in \a this.
3657 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3659 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3660 * \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.
3661 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3663 * \throw If \a there is a null pointer in \a ms.
3664 * \sa MEDFileUMesh::setMeshAtLevel
3666 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3670 const MEDCouplingUMesh *mRef=ms[0];
3672 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3673 std::string name(mRef->getName());
3674 const DataArrayDouble *coo(mRef->getCoords());
3677 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3679 const MEDCouplingUMesh *cur(*it);
3681 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3682 if(coo!=cur->getCoords())
3683 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3684 int mdim=cur->getMeshDimension();
3685 zeDim=std::max(zeDim,mdim);
3686 if(s.find(mdim)!=s.end())
3687 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3689 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3691 int mdim=(*it)->getMeshDimension();
3692 setName((*it)->getName());
3693 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3699 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3700 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3701 * The given meshes must share the same node coordinates array.
3702 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3703 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3704 * create in \a this mesh.
3705 * \throw If \a ms is empty.
3706 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3707 * to the existing meshes of other levels of \a this mesh.
3708 * \throw If the meshes in \a ms do not share the same node coordinates array.
3709 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3710 * of the given meshes.
3711 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3712 * \throw If names of some meshes in \a ms are equal.
3713 * \throw If \a ms includes a mesh with an empty name.
3715 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3718 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3719 int sz=(-meshDimRelToMax)+1;
3720 if(sz>=(int)_ms.size())
3722 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3723 DataArrayDouble *coo=checkMultiMesh(ms);
3724 if((DataArrayDouble *)_coords==0)
3730 if((DataArrayDouble *)_coords!=coo)
3731 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3732 std::vector<DataArrayInt *> corr;
3733 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3734 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3735 setMeshAtLevel(meshDimRelToMax,m,renum);
3736 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3737 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3741 * Creates groups at a given level in \a this mesh from a sequence of
3742 * meshes each representing a group.
3743 * The given meshes must share the same node coordinates array.
3744 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3745 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3746 * create in \a this mesh.
3747 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3749 * \throw If \a ms is empty.
3750 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3751 * to the existing meshes of other levels of \a this mesh.
3752 * \throw If the meshes in \a ms do not share the same node coordinates array.
3753 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3754 * of the given meshes.
3755 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3756 * \throw If names of some meshes in \a ms are equal.
3757 * \throw If \a ms includes a mesh with an empty name.
3759 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3762 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3763 int sz=(-meshDimRelToMax)+1;
3764 if(sz>=(int)_ms.size())
3766 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3767 DataArrayDouble *coo=checkMultiMesh(ms);
3768 if((DataArrayDouble *)_coords==0)
3774 if((DataArrayDouble *)_coords!=coo)
3775 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3776 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3777 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3779 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3781 DataArrayInt *arr=0;
3782 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3786 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3787 throw INTERP_KERNEL::Exception(oss.str().c_str());
3790 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3791 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3794 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
3796 const DataArrayDouble *ret=ms[0]->getCoords();
3797 int mdim=ms[0]->getMeshDimension();
3798 for(unsigned int i=1;i<ms.size();i++)
3800 ms[i]->checkCoherency();
3801 if(ms[i]->getCoords()!=ret)
3802 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3803 if(ms[i]->getMeshDimension()!=mdim)
3804 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3806 return const_cast<DataArrayDouble *>(ret);
3810 * Sets the family field of a given relative dimension.
3811 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3812 * the family field is set.
3813 * \param [in] famArr - the array of the family field.
3814 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3815 * \throw If \a famArr has an invalid size.
3817 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
3819 if(meshDimRelToMaxExt==1)
3826 DataArrayDouble *coo(_coords);
3828 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3829 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3834 if(meshDimRelToMaxExt>1)
3835 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3836 int traducedRk=-meshDimRelToMaxExt;
3837 if(traducedRk>=(int)_ms.size())
3838 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3839 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3840 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3841 return _ms[traducedRk]->setFamilyArr(famArr);
3845 * Sets the optional numbers of mesh entities of a given dimension.
3846 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3847 * \param [in] renumArr - the array of the numbers.
3848 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3849 * \throw If \a renumArr has an invalid size.
3851 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
3853 if(meshDimRelToMaxExt==1)
3861 DataArrayDouble *coo(_coords);
3863 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3864 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3865 renumArr->incrRef();
3866 _num_coords=renumArr;
3870 if(meshDimRelToMaxExt>1)
3871 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3872 int traducedRk=-meshDimRelToMaxExt;
3873 if(traducedRk>=(int)_ms.size())
3874 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3875 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3876 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3877 return _ms[traducedRk]->setRenumArr(renumArr);
3881 * Sets the optional names of mesh entities of a given dimension.
3882 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3883 * \param [in] nameArr - the array of the names.
3884 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3885 * \throw If \a nameArr has an invalid size.
3887 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
3889 if(meshDimRelToMaxExt==1)
3896 DataArrayDouble *coo(_coords);
3898 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3899 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3901 _name_coords=nameArr;
3904 if(meshDimRelToMaxExt>1)
3905 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3906 int traducedRk=-meshDimRelToMaxExt;
3907 if(traducedRk>=(int)_ms.size())
3908 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3909 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3910 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3911 return _ms[traducedRk]->setNameArr(nameArr);
3914 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3916 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3917 if((const MEDFileUMeshSplitL1 *)(*it))
3918 (*it)->synchronizeTinyInfo(*this);
3922 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3924 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
3926 DataArrayInt *arr=_fam_coords;
3928 arr->changeValue(oldId,newId);
3929 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3931 MEDFileUMeshSplitL1 *sp=(*it);
3934 sp->changeFamilyIdArr(oldId,newId);
3939 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3941 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3942 const DataArrayInt *da(_fam_coords);
3944 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3945 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3947 const MEDFileUMeshSplitL1 *elt(*it);
3950 da=elt->getFamilyField();
3952 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3958 void MEDFileUMesh::computeRevNum() const
3960 if((const DataArrayInt *)_num_coords)
3963 int maxValue=_num_coords->getMaxValue(pos);
3964 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3968 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
3970 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
3973 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
3975 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
3976 ret.push_back((const DataArrayInt *)_fam_nodes);
3977 ret.push_back((const DataArrayInt *)_num_nodes);
3978 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
3979 ret.push_back((const DataArrayInt *)_fam_cells);
3980 ret.push_back((const DataArrayInt *)_num_cells);
3981 ret.push_back((const DataArrayAsciiChar *)_names_cells);
3982 ret.push_back((const DataArrayInt *)_fam_faces);
3983 ret.push_back((const DataArrayInt *)_num_faces);
3984 ret.push_back((const DataArrayInt *)_rev_num_nodes);
3985 ret.push_back((const DataArrayAsciiChar *)_names_faces);
3986 ret.push_back((const DataArrayInt *)_rev_num_cells);
3987 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
3991 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
3993 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3994 if((const DataArrayInt *)_fam_nodes)
3996 int val=_fam_nodes->getMaxValue(tmp);
3997 ret=std::max(ret,std::abs(val));
3999 if((const DataArrayInt *)_fam_cells)
4001 int val=_fam_cells->getMaxValue(tmp);
4002 ret=std::max(ret,std::abs(val));
4004 if((const DataArrayInt *)_fam_faces)
4006 int val=_fam_faces->getMaxValue(tmp);
4007 ret=std::max(ret,std::abs(val));
4012 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4014 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4015 if((const DataArrayInt *)_fam_nodes)
4017 int val=_fam_nodes->getMaxValue(tmp);
4018 ret=std::max(ret,val);
4020 if((const DataArrayInt *)_fam_cells)
4022 int val=_fam_cells->getMaxValue(tmp);
4023 ret=std::max(ret,val);
4025 if((const DataArrayInt *)_fam_faces)
4027 int val=_fam_faces->getMaxValue(tmp);
4028 ret=std::max(ret,val);
4033 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4035 int ret=std::numeric_limits<int>::max(),tmp=-1;
4036 if((const DataArrayInt *)_fam_nodes)
4038 int val=_fam_nodes->getMinValue(tmp);
4039 ret=std::min(ret,val);
4041 if((const DataArrayInt *)_fam_cells)
4043 int val=_fam_cells->getMinValue(tmp);
4044 ret=std::min(ret,val);
4046 if((const DataArrayInt *)_fam_faces)
4048 int val=_fam_faces->getMinValue(tmp);
4049 ret=std::min(ret,val);
4054 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4056 if(!MEDFileMesh::isEqual(other,eps,what))
4058 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4061 what="Mesh types differ ! This is structured and other is NOT !";
4064 const DataArrayInt *famc1=_fam_nodes;
4065 const DataArrayInt *famc2=otherC->_fam_nodes;
4066 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4068 what="Mismatch of families arr on nodes ! One is defined and not other !";
4073 bool ret=famc1->isEqual(*famc2);
4076 what="Families arr on nodes differ !";
4081 famc2=otherC->_fam_cells;
4082 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4084 what="Mismatch of families arr on cells ! One is defined and not other !";
4089 bool ret=famc1->isEqual(*famc2);
4092 what="Families arr on cells differ !";
4097 famc2=otherC->_fam_faces;
4098 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4100 what="Mismatch of families arr on faces ! One is defined and not other !";
4105 bool ret=famc1->isEqual(*famc2);
4108 what="Families arr on faces differ !";
4113 famc2=otherC->_num_nodes;
4114 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4116 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4121 bool ret=famc1->isEqual(*famc2);
4124 what="Numbering arr on nodes differ !";
4129 famc2=otherC->_num_cells;
4130 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4132 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4137 bool ret=famc1->isEqual(*famc2);
4140 what="Numbering arr on cells differ !";
4145 famc2=otherC->_num_faces;
4146 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4148 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4153 bool ret=famc1->isEqual(*famc2);
4156 what="Numbering arr on faces differ !";
4160 const DataArrayAsciiChar *d1=_names_cells;
4161 const DataArrayAsciiChar *d2=otherC->_names_cells;
4162 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4164 what="Mismatch of naming arr on cells ! One is defined and not other !";
4169 bool ret=d1->isEqual(*d2);
4172 what="Naming arr on cells differ !";
4177 d2=otherC->_names_faces;
4178 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4180 what="Mismatch of naming arr on faces ! One is defined and not other !";
4185 bool ret=d1->isEqual(*d2);
4188 what="Naming arr on faces differ !";
4193 d2=otherC->_names_nodes;
4194 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4196 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4201 bool ret=d1->isEqual(*d2);
4204 what="Naming arr on nodes differ !";
4211 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4213 MEDFileMesh::clearNonDiscrAttributes();
4214 const DataArrayInt *tmp=_fam_nodes;
4216 (const_cast<DataArrayInt *>(tmp))->setName("");
4219 (const_cast<DataArrayInt *>(tmp))->setName("");
4222 (const_cast<DataArrayInt *>(tmp))->setName("");
4225 (const_cast<DataArrayInt *>(tmp))->setName("");
4228 (const_cast<DataArrayInt *>(tmp))->setName("");
4231 (const_cast<DataArrayInt *>(tmp))->setName("");
4235 * Returns ids of mesh entities contained in given families of a given dimension.
4236 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4238 * \param [in] fams - the names of the families of interest.
4239 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4240 * returned instead of ids.
4241 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4242 * numbers, if available and required, of mesh entities of the families. The caller
4243 * is to delete this array using decrRef() as it is no more needed.
4244 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4246 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4248 std::vector<int> famIds(getFamiliesIds(fams));
4249 switch(meshDimRelToMaxExt)
4253 if((const DataArrayInt *)_fam_nodes)
4255 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4257 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4259 da=_fam_nodes->getIdsEqualList(0,0);
4261 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4266 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4271 if((const DataArrayInt *)_fam_cells)
4273 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4275 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4277 da=_fam_cells->getIdsEqualList(0,0);
4279 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4284 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4289 if((const DataArrayInt *)_fam_faces)
4291 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4293 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4295 da=_fam_faces->getIdsEqualList(0,0);
4297 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
4302 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
4306 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
4308 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
4312 * Sets the family field of a given relative dimension.
4313 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4314 * the family field is set.
4315 * \param [in] famArr - the array of the family field.
4316 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4317 * \throw If \a famArr has an invalid size.
4318 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
4320 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4322 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4324 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4325 switch(meshDimRelToMaxExt)
4329 int nbCells=mesh->getNumberOfCells();
4330 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4336 int nbNodes=mesh->getNumberOfNodes();
4337 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4343 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4344 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
4349 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
4356 * Sets the optional numbers of mesh entities of a given dimension.
4357 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4358 * \param [in] renumArr - the array of the numbers.
4359 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4360 * \throw If \a renumArr has an invalid size.
4361 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4363 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4365 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4367 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4368 switch(meshDimRelToMaxExt)
4372 int nbCells=mesh->getNumberOfCells();
4373 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4374 _num_cells=renumArr;
4379 int nbNodes=mesh->getNumberOfNodes();
4380 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4381 _num_nodes=renumArr;
4386 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4387 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
4388 _num_faces=renumArr;
4392 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
4395 renumArr->incrRef();
4399 * Sets the optional names of mesh entities of a given dimension.
4400 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4401 * \param [in] nameArr - the array of the names.
4402 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4403 * \throw If \a nameArr has an invalid size.
4405 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4407 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4409 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4410 switch(meshDimRelToMaxExt)
4414 int nbCells=mesh->getNumberOfCells();
4415 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4416 _names_cells=nameArr;
4421 int nbNodes=mesh->getNumberOfNodes();
4422 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4423 _names_nodes=nameArr;
4428 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4429 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
4430 _names_cells=nameArr;
4433 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4440 * Returns the family field for mesh entities of a given dimension.
4441 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4442 * \return const DataArrayInt * - the family field. It is an array of ids of families
4443 * each mesh entity belongs to. It can be \c NULL.
4444 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4446 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
4448 switch(meshDimRelToMaxExt)
4457 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4462 * Returns the optional numbers of mesh entities of a given dimension.
4463 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4464 * \return const DataArrayInt * - the array of the entity numbers.
4465 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4466 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4468 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
4470 switch(meshDimRelToMaxExt)
4479 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4484 * Returns the optional numbers of mesh entities of a given dimension transformed using
4485 * DataArrayInt::invertArrayN2O2O2N().
4486 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4487 * \return const DataArrayInt * - the array of the entity numbers transformed using
4488 * DataArrayInt::invertArrayN2O2O2N().
4489 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4490 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4492 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
4494 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4495 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4496 if(meshDimRelToMaxExt==0)
4498 if((const DataArrayInt *)_num_cells)
4501 int maxValue=_num_cells->getMaxValue(pos);
4502 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4503 return _rev_num_cells;
4506 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4510 if((const DataArrayInt *)_num_nodes)
4513 int maxValue=_num_nodes->getMaxValue(pos);
4514 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4515 return _rev_num_nodes;
4518 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4522 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
4524 switch(meshDimRelToMaxExt)
4527 return _names_cells;
4529 return _names_nodes;
4531 return _names_faces;
4533 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4538 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4539 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4541 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4543 std::vector<int> ret(1);
4548 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4549 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4551 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4553 std::vector<int> ret(2);
4559 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4561 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4563 std::vector<int> ret;
4564 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
4575 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4577 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4579 std::vector<int> ret;
4580 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
4591 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4593 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4595 std::vector<int> ret;
4596 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
4607 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4609 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4611 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4615 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
4617 DataArrayInt *arr=_fam_nodes;
4619 arr->changeValue(oldId,newId);
4622 arr->changeValue(oldId,newId);
4625 arr->changeValue(oldId,newId);
4628 void MEDFileStructuredMesh::deepCpyAttributes()
4630 if((const DataArrayInt*)_fam_nodes)
4631 _fam_nodes=_fam_nodes->deepCpy();
4632 if((const DataArrayInt*)_num_nodes)
4633 _num_nodes=_num_nodes->deepCpy();
4634 if((const DataArrayAsciiChar*)_names_nodes)
4635 _names_nodes=_names_nodes->deepCpy();
4636 if((const DataArrayInt*)_fam_cells)
4637 _fam_cells=_fam_cells->deepCpy();
4638 if((const DataArrayInt*)_num_cells)
4639 _num_cells=_num_cells->deepCpy();
4640 if((const DataArrayAsciiChar*)_names_cells)
4641 _names_cells=_names_cells->deepCpy();
4642 if((const DataArrayInt*)_fam_faces)
4643 _fam_faces=_fam_faces->deepCpy();
4644 if((const DataArrayInt*)_num_faces)
4645 _num_faces=_num_faces->deepCpy();
4646 if((const DataArrayAsciiChar*)_names_faces)
4647 _names_faces=_names_faces->deepCpy();
4648 if((const DataArrayInt*)_rev_num_nodes)
4649 _rev_num_nodes=_rev_num_nodes->deepCpy();
4650 if((const DataArrayInt*)_rev_num_cells)
4651 _rev_num_cells=_rev_num_cells->deepCpy();
4655 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4657 * \return a pointer to cartesian mesh that need to be managed by the caller.
4658 * \warning the returned pointer has to be managed by the caller.
4662 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4663 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
4664 * \param [in] renum - it must be \c false.
4665 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4666 * delete using decrRef() as it is no more needed.
4668 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
4671 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4672 const MEDCouplingStructuredMesh *m(getStructuredMesh());
4673 switch(meshDimRelToMax)
4679 return const_cast<MEDCouplingStructuredMesh *>(m);
4684 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
4685 buildMinusOneImplicitPartIfNeeded();
4686 MEDCouplingMesh *ret(_faces_if_necessary);
4692 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4697 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4698 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4699 * \return int - the number of entities.
4700 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4702 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
4704 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4706 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4707 switch(meshDimRelToMaxExt)
4710 return cmesh->getNumberOfCells();
4712 return cmesh->getNumberOfNodes();
4714 return cmesh->getNumberOfCellsOfSubLevelMesh();
4716 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
4720 int MEDFileStructuredMesh::getNumberOfNodes() const
4722 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4724 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4725 return cmesh->getNumberOfNodes();
4728 bool MEDFileStructuredMesh::hasImplicitPart() const
4734 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
4736 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
4738 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
4739 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
4742 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
4743 if(cm.getReverseExtrudedType()!=gt)
4744 throw INTERP_KERNEL::Exception(MSG);
4745 buildImplicitPart();
4746 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
4750 if(gt!=zeFaceMesh->getCellModelEnum())
4751 throw INTERP_KERNEL::Exception(MSG);
4752 return zeFaceMesh->getNumberOfCells();
4756 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
4758 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
4760 buildImplicitPart();
4763 void MEDFileStructuredMesh::buildImplicitPart() const
4765 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
4767 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
4768 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
4771 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
4773 _faces_if_necessary=0;
4777 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
4778 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
4780 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
4782 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
4784 return _faces_if_necessary;
4787 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
4789 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4791 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
4792 switch(meshDimRelToMax)
4796 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
4801 int mdim(cmesh->getMeshDimension());
4803 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
4804 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
4808 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
4812 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
4814 if(st.getNumberOfItems()!=1)
4815 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 !");
4816 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4817 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4818 if(getNumberOfNodes()!=(int)nodesFetched.size())
4819 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4820 if(st[0].getPflName().empty())
4822 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4825 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
4826 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4827 int sz(nodesFetched.size());
4828 for(const int *work=arr->begin();work!=arr->end();work++)
4830 std::vector<int> conn;
4831 cmesh->getNodeIdsOfCell(*work,conn);
4832 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4833 if(*it>=0 && *it<sz)
4834 nodesFetched[*it]=true;
4836 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4840 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
4842 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
4846 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
4847 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
4849 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4850 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
4852 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4855 if(!mrs || mrs->isCellFamilyFieldReading())
4857 famCells=DataArrayInt::New();
4858 famCells->alloc(nbOfElt,1);
4859 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
4862 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4865 if(!mrs || mrs->isCellNumFieldReading())
4867 numCells=DataArrayInt::New();
4868 numCells->alloc(nbOfElt,1);
4869 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
4872 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4875 if(!mrs || mrs->isCellNameFieldReading())
4877 namesCells=DataArrayAsciiChar::New();
4878 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4879 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
4880 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4885 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4887 setName(strm->getName());
4888 setDescription(strm->getDescription());
4889 setUnivName(strm->getUnivName());
4890 setIteration(strm->getIteration());
4891 setOrder(strm->getOrder());
4892 setTimeValue(strm->getTime());
4893 setTimeUnit(strm->getTimeUnit());
4894 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4895 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4896 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4899 if(!mrs || mrs->isNodeFamilyFieldReading())
4901 int nbNodes(getNumberOfNodes());
4903 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
4904 _fam_nodes=DataArrayInt::New();
4905 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
4906 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...
4907 _fam_nodes->fillWithZero();
4908 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4911 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4914 if(!mrs || mrs->isNodeNumFieldReading())
4916 _num_nodes=DataArrayInt::New();
4917 _num_nodes->alloc(nbOfElt,1);
4918 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4921 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4924 if(!mrs || mrs->isNodeNameFieldReading())
4926 _names_nodes=DataArrayAsciiChar::New();
4927 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4928 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4929 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4932 int meshDim(getStructuredMesh()->getMeshDimension());
4933 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
4935 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
4938 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
4940 int meshDim(getStructuredMesh()->getMeshDimension());
4941 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
4943 if((const DataArrayInt *)_fam_cells)
4944 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4945 if((const DataArrayInt *)_fam_faces)
4946 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
4947 if((const DataArrayInt *)_fam_nodes)
4948 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4949 if((const DataArrayInt *)_num_cells)
4950 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4951 if((const DataArrayInt *)_num_faces)
4952 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
4953 if((const DataArrayInt *)_num_nodes)
4954 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4955 if((const DataArrayAsciiChar *)_names_cells)
4957 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4959 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4960 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4961 throw INTERP_KERNEL::Exception(oss.str().c_str());
4963 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4965 if((const DataArrayAsciiChar *)_names_faces)
4967 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
4969 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
4970 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
4971 throw INTERP_KERNEL::Exception(oss.str().c_str());
4973 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
4975 if((const DataArrayAsciiChar *)_names_nodes)
4977 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4979 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4980 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4981 throw INTERP_KERNEL::Exception(oss.str().c_str());
4983 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4986 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
4990 * Returns an empty instance of MEDFileCMesh.
4991 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4992 * mesh using decrRef() as it is no more needed.
4994 MEDFileCMesh *MEDFileCMesh::New()
4996 return new MEDFileCMesh;
5000 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5001 * file. The first mesh in the file is loaded.
5002 * \param [in] fileName - the name of MED file to read.
5003 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5004 * mesh using decrRef() as it is no more needed.
5005 * \throw If the file is not readable.
5006 * \throw If there is no meshes in the file.
5007 * \throw If the mesh in the file is not a Cartesian one.
5009 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5011 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5014 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5015 throw INTERP_KERNEL::Exception(oss.str().c_str());
5017 MEDFileUtilities::CheckFileForRead(fileName);
5018 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5020 ParaMEDMEM::MEDCouplingMeshType meshType;
5022 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5023 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5027 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5028 * file. The mesh to load is specified by its name and numbers of a time step and an
5030 * \param [in] fileName - the name of MED file to read.
5031 * \param [in] mName - the name of the mesh to read.
5032 * \param [in] dt - the number of a time step.
5033 * \param [in] it - the number of an iteration.
5034 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5035 * mesh using decrRef() as it is no more needed.
5036 * \throw If the file is not readable.
5037 * \throw If there is no mesh with given attributes in the file.
5038 * \throw If the mesh in the file is not a Cartesian one.
5040 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5042 MEDFileUtilities::CheckFileForRead(fileName);
5043 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5044 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5047 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5049 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5052 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5054 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5055 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5060 * Returns the dimension on cells in \a this mesh.
5061 * \return int - the mesh dimension.
5062 * \throw If there are no cells in this mesh.
5064 int MEDFileCMesh::getMeshDimension() const
5066 if(!((const MEDCouplingCMesh*)_cmesh))
5067 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5068 return _cmesh->getMeshDimension();
5072 * Returns the dimension on nodes in \a this mesh.
5073 * \return int - the space dimension.
5074 * \throw If there are no cells in this mesh.
5076 int MEDFileCMesh::getSpaceDimension() const
5078 if(!((const MEDCouplingCMesh*)_cmesh))
5079 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5080 return _cmesh->getSpaceDimension();
5084 * Returns a string describing \a this mesh.
5085 * \return std::string - the mesh information string.
5087 std::string MEDFileCMesh::simpleRepr() const
5089 return MEDFileStructuredMesh::simpleRepr();
5093 * Returns a full textual description of \a this mesh.
5094 * \return std::string - the string holding the mesh description.
5096 std::string MEDFileCMesh::advancedRepr() const
5098 return simpleRepr();
5101 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5103 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5107 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5109 return new MEDFileCMesh;
5112 MEDFileMesh *MEDFileCMesh::deepCpy() const
5114 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5115 if((const MEDCouplingCMesh*)_cmesh)
5116 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5117 ret->deepCpyAttributes();
5122 * Checks if \a this and another mesh are equal.
5123 * \param [in] other - the mesh to compare with.
5124 * \param [in] eps - a precision used to compare real values.
5125 * \param [in,out] what - the string returning description of unequal data.
5126 * \return bool - \c true if the meshes are equal, \c false, else.
5128 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5130 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5132 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5135 what="Mesh types differ ! This is cartesian and other is NOT !";
5138 clearNonDiscrAttributes();
5139 otherC->clearNonDiscrAttributes();
5140 const MEDCouplingCMesh *coo1=_cmesh;
5141 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5142 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5144 what="Mismatch of cartesian meshes ! One is defined and not other !";
5149 bool ret=coo1->isEqual(coo2,eps);
5152 what="cartesian meshes differ !";
5160 * Clears redundant attributes of incorporated data arrays.
5162 void MEDFileCMesh::clearNonDiscrAttributes() const
5164 MEDFileStructuredMesh::clearNonDiscrAttributes();
5165 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
5168 MEDFileCMesh::MEDFileCMesh()
5172 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5175 loadCMeshFromFile(fid,mName,dt,it,mrs);
5177 catch(INTERP_KERNEL::Exception& e)
5182 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5184 ParaMEDMEM::MEDCouplingMeshType meshType;
5187 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5188 if(meshType!=CARTESIAN)
5190 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
5191 throw INTERP_KERNEL::Exception(oss.str().c_str());
5193 MEDFileCMeshL2 loaderl2;
5194 loaderl2.loadAll(fid,mid,mName,dt,it);
5195 MEDCouplingCMesh *mesh=loaderl2.getMesh();
5198 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5202 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
5203 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
5205 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
5207 synchronizeTinyInfoOnLeaves();
5211 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
5213 synchronizeTinyInfoOnLeaves();
5218 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
5219 * \param [in] m - the new MEDCouplingCMesh to refer to.
5220 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5223 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
5225 dealWithTinyInfo(m);
5231 void MEDFileCMesh::writeLL(med_idt fid) const
5233 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5234 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5235 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5236 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5237 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5238 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5239 int spaceDim(_cmesh->getSpaceDimension());
5240 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5241 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5242 for(int i=0;i<spaceDim;i++)
5244 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
5246 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5247 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
5248 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
5250 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5251 MEDmeshUniversalNameWr(fid,maa);
5252 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
5253 for(int i=0;i<spaceDim;i++)
5255 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
5256 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
5259 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5260 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5263 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
5265 const MEDCouplingCMesh *cmesh=_cmesh;
5268 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
5269 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
5270 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
5271 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
5274 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
5276 return new MEDFileCurveLinearMesh;
5279 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5281 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5284 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5285 throw INTERP_KERNEL::Exception(oss.str().c_str());
5287 MEDFileUtilities::CheckFileForRead(fileName);
5288 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5290 ParaMEDMEM::MEDCouplingMeshType meshType;
5292 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5293 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
5296 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5298 MEDFileUtilities::CheckFileForRead(fileName);
5299 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5300 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
5303 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
5305 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5308 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
5310 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5311 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5315 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5317 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5321 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5323 return new MEDFileCurveLinearMesh;
5326 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5328 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5329 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5330 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5331 ret->deepCpyAttributes();
5335 int MEDFileCurveLinearMesh::getMeshDimension() const
5337 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5338 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5339 return _clmesh->getMeshDimension();
5342 std::string MEDFileCurveLinearMesh::simpleRepr() const
5344 return MEDFileStructuredMesh::simpleRepr();
5347 std::string MEDFileCurveLinearMesh::advancedRepr() const
5349 return simpleRepr();
5352 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5354 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5356 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5359 what="Mesh types differ ! This is curve linear and other is NOT !";
5362 clearNonDiscrAttributes();
5363 otherC->clearNonDiscrAttributes();
5364 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5365 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5366 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5368 what="Mismatch of curve linear meshes ! One is defined and not other !";
5373 bool ret=coo1->isEqual(coo2,eps);
5376 what="curve linear meshes differ !";
5383 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
5385 MEDFileStructuredMesh::clearNonDiscrAttributes();
5386 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
5389 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
5391 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
5394 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
5395 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
5396 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
5397 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
5400 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
5402 synchronizeTinyInfoOnLeaves();
5406 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
5408 dealWithTinyInfo(m);
5414 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
5416 synchronizeTinyInfoOnLeaves();
5420 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
5424 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5427 loadCLMeshFromFile(fid,mName,dt,it,mrs);
5429 catch(INTERP_KERNEL::Exception& e)
5434 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
5436 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5437 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5438 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5439 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5440 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5441 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5442 int spaceDim=_clmesh->getSpaceDimension();
5443 int meshDim=_clmesh->getMeshDimension();
5444 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5445 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5446 const DataArrayDouble *coords=_clmesh->getCoords();
5448 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5449 for(int i=0;i<spaceDim;i++)
5451 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5453 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5454 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
5455 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
5457 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5458 MEDmeshUniversalNameWr(fid,maa);
5459 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5460 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5461 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5463 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5465 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5466 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5469 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5471 ParaMEDMEM::MEDCouplingMeshType meshType;
5474 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5475 if(meshType!=CURVE_LINEAR)
5477 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5478 throw INTERP_KERNEL::Exception(oss.str().c_str());
5480 MEDFileCLMeshL2 loaderl2;
5481 loaderl2.loadAll(fid,mid,mName,dt,it);
5482 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5485 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5488 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5490 return new MEDFileMeshMultiTS;
5493 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
5495 return new MEDFileMeshMultiTS(fileName);
5498 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
5500 return new MEDFileMeshMultiTS(fileName,mName);
5503 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
5505 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5506 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5508 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5509 if((const MEDFileMesh *)*it)
5510 meshOneTs[i]=(*it)->deepCpy();
5511 ret->_mesh_one_ts=meshOneTs;
5515 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
5517 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5520 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
5522 std::vector<const BigMemoryObject *> ret;
5523 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5524 ret.push_back((const MEDFileMesh *)*it);
5528 std::string MEDFileMeshMultiTS::getName() const
5530 if(_mesh_one_ts.empty())
5531 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5532 return _mesh_one_ts[0]->getName();
5535 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
5537 std::string oldName(getName());
5538 std::vector< std::pair<std::string,std::string> > v(1);
5539 v[0].first=oldName; v[0].second=newMeshName;
5543 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5546 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5548 MEDFileMesh *cur(*it);
5550 ret=cur->changeNames(modifTab) || ret;
5555 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
5557 if(_mesh_one_ts.empty())
5558 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5559 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5562 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
5565 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5566 _mesh_one_ts.resize(1);
5567 mesh1TimeStep->incrRef();
5568 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5569 _mesh_one_ts[0]=mesh1TimeStep;
5572 void MEDFileMeshMultiTS::write(med_idt fid) const
5574 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5576 (*it)->copyOptionsFrom(*this);
5581 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
5583 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5584 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5585 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5586 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5590 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
5591 {//for the moment to be improved
5592 _mesh_one_ts.resize(1);
5593 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5596 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5600 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
5603 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5606 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5607 throw INTERP_KERNEL::Exception(oss.str().c_str());
5609 MEDFileUtilities::CheckFileForRead(fileName);
5610 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5612 ParaMEDMEM::MEDCouplingMeshType meshType;
5614 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5615 loadFromFile(fileName,ms.front());
5617 catch(INTERP_KERNEL::Exception& e)
5622 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
5625 loadFromFile(fileName,mName);
5627 catch(INTERP_KERNEL::Exception& e)
5632 MEDFileMeshes *MEDFileMeshes::New()
5634 return new MEDFileMeshes;
5637 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
5639 return new MEDFileMeshes(fileName);
5642 void MEDFileMeshes::write(med_idt fid) const
5645 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5647 (*it)->copyOptionsFrom(*this);
5652 void MEDFileMeshes::write(const std::string& fileName, int mode) const
5654 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5655 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5656 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5657 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5662 int MEDFileMeshes::getNumberOfMeshes() const
5664 return _meshes.size();
5667 MEDFileMeshesIterator *MEDFileMeshes::iterator()
5669 return new MEDFileMeshesIterator(this);
5672 /** Return a borrowed reference (caller is not responsible) */
5673 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
5675 if(i<0 || i>=(int)_meshes.size())
5677 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5678 throw INTERP_KERNEL::Exception(oss.str().c_str());
5680 return _meshes[i]->getOneTimeStep();
5683 /** Return a borrowed reference (caller is not responsible) */
5684 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
5686 std::vector<std::string> ms=getMeshesNames();
5687 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5690 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5691 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5692 throw INTERP_KERNEL::Exception(oss.str().c_str());
5694 return getMeshAtPos((int)std::distance(ms.begin(),it));
5697 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
5699 std::vector<std::string> ret(_meshes.size());
5701 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5703 const MEDFileMeshMultiTS *f=(*it);
5706 ret[i]=f->getName();
5710 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5711 throw INTERP_KERNEL::Exception(oss.str().c_str());
5717 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5720 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5722 MEDFileMeshMultiTS *cur(*it);
5724 ret=cur->changeNames(modifTab) || ret;
5729 void MEDFileMeshes::resize(int newSize)
5731 _meshes.resize(newSize);
5734 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
5737 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5738 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5739 elt->setOneTimeStep(mesh);
5740 _meshes.push_back(elt);
5743 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
5746 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5747 if(i>=(int)_meshes.size())
5748 _meshes.resize(i+1);
5749 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5750 elt->setOneTimeStep(mesh);
5754 void MEDFileMeshes::destroyMeshAtPos(int i)
5756 if(i<0 || i>=(int)_meshes.size())
5758 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5759 throw INTERP_KERNEL::Exception(oss.str().c_str());
5761 _meshes.erase(_meshes.begin()+i);
5764 void MEDFileMeshes::loadFromFile(const std::string& fileName)
5766 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5768 _meshes.resize(ms.size());
5769 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5770 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
5773 MEDFileMeshes::MEDFileMeshes()
5777 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
5780 loadFromFile(fileName);
5782 catch(INTERP_KERNEL::Exception& /*e*/)
5786 MEDFileMeshes *MEDFileMeshes::deepCpy() const
5788 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5790 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5791 if((const MEDFileMeshMultiTS *)*it)
5792 meshes[i]=(*it)->deepCpy();
5793 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5794 ret->_meshes=meshes;
5798 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
5800 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5803 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
5805 std::vector<const BigMemoryObject *> ret;
5806 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5807 ret.push_back((const MEDFileMeshMultiTS *)*it);
5811 std::string MEDFileMeshes::simpleRepr() const
5813 std::ostringstream oss;
5814 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5815 simpleReprWithoutHeader(oss);
5819 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5821 int nbOfMeshes=getNumberOfMeshes();
5822 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5823 std::vector<std::string> mns=getMeshesNames();
5824 for(int i=0;i<nbOfMeshes;i++)
5825 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5828 void MEDFileMeshes::checkCoherency() const
5830 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5832 std::set<std::string> s;
5833 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5835 const MEDFileMeshMultiTS *elt=(*it);
5838 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5839 throw INTERP_KERNEL::Exception(oss.str().c_str());
5841 std::size_t sz=s.size();
5842 s.insert(std::string((*it)->getName()));
5845 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5846 throw INTERP_KERNEL::Exception(oss.str().c_str());
5851 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5856 _nb_iter=ms->getNumberOfMeshes();
5860 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5864 MEDFileMesh *MEDFileMeshesIterator::nextt()
5866 if(_iter_id<_nb_iter)
5868 MEDFileMeshes *ms(_ms);
5870 return ms->getMeshAtPos(_iter_id++);