1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileUtilities.hxx"
23 #include "MEDFileFieldOverView.hxx"
24 #include "MEDFileField.hxx"
25 #include "MEDLoader.hxx"
26 #include "MEDLoaderBase.hxx"
28 #include "MEDCouplingUMesh.hxx"
30 #include "InterpKernelAutoPtr.hxx"
35 extern med_geometry_type typmai3[34];
37 using namespace ParaMEDMEM;
39 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
41 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
45 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
47 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
48 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
50 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
51 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
52 ret+=(*it2).capacity();
54 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
55 ret+=(*it).first.capacity()+sizeof(int);
59 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
61 return std::vector<const BigMemoryObject *>();
65 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
66 * file. The first mesh in the file is loaded.
67 * \param [in] fileName - the name of MED file to read.
68 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
69 * mesh using decrRef() as it is no more needed.
70 * \throw If the file is not readable.
71 * \throw If there is no meshes in the file.
72 * \throw If the mesh in the file is of a not supported type.
74 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
76 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
79 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
80 throw INTERP_KERNEL::Exception(oss.str().c_str());
82 MEDFileUtilities::CheckFileForRead(fileName);
83 ParaMEDMEM::MEDCouplingMeshType meshType;
84 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
87 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
92 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
93 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
94 return (MEDFileUMesh *)ret.retn();
98 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
99 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
100 return (MEDFileCMesh *)ret.retn();
104 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
105 ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
106 return (MEDFileCurveLinearMesh *)ret.retn();
110 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
111 throw INTERP_KERNEL::Exception(oss.str().c_str());
117 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
118 * file. The mesh to load is specified by its name and numbers of a time step and an
120 * \param [in] fileName - the name of MED file to read.
121 * \param [in] mName - the name of the mesh to read.
122 * \param [in] dt - the number of a time step.
123 * \param [in] it - the number of an iteration.
124 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
125 * mesh using decrRef() as it is no more needed.
126 * \throw If the file is not readable.
127 * \throw If there is no mesh with given attributes in the file.
128 * \throw If the mesh in the file is of a not supported type.
130 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
132 MEDFileUtilities::CheckFileForRead(fileName);
133 ParaMEDMEM::MEDCouplingMeshType meshType;
134 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
137 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
142 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
143 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
144 return (MEDFileUMesh *)ret.retn();
148 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
149 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
150 return (MEDFileCMesh *)ret.retn();
154 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
155 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
156 return (MEDFileCurveLinearMesh *)ret.retn();
160 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
161 throw INTERP_KERNEL::Exception(oss.str().c_str());
167 * Writes \a this mesh into an open MED file specified by its descriptor.
168 * \param [in] fid - the MED file descriptor.
169 * \throw If the mesh name is not set.
170 * \throw If the file is open for reading only.
171 * \throw If the writing mode == 1 and the same data is present in an existing file.
173 void MEDFileMesh::write(med_idt fid) const
176 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
178 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
183 * Writes \a this mesh into a MED file specified by its name.
184 * \param [in] fileName - the MED file name.
185 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
186 * - 2 - erase; an existing file is removed.
187 * - 1 - append; same data should not be present in an existing file.
188 * - 0 - overwrite; same data present in an existing file is overwritten.
189 * \throw If the mesh name is not set.
190 * \throw If \a mode == 1 and the same data is present in an existing file.
192 void MEDFileMesh::write(const std::string& fileName, int mode) const
194 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
195 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
196 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
197 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
202 * Checks if \a this and another mesh are equal.
203 * \param [in] other - the mesh to compare with.
204 * \param [in] eps - a precision used to compare real values.
205 * \param [in,out] what - the string returning description of unequal data.
206 * \return bool - \c true if the meshes are equal, \c false, else.
208 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
210 if(_order!=other->_order)
212 what="Orders differ !";
215 if(_iteration!=other->_iteration)
217 what="Iterations differ !";
220 if(fabs(_time-other->_time)>eps)
222 what="Time values differ !";
225 if(_dt_unit!=other->_dt_unit)
227 what="Time units differ !";
230 if(_name!=other->_name)
232 what="Names differ !";
235 //univ_name has been ignored -> not a bug because it is a mutable attribute
236 if(_desc_name!=other->_desc_name)
238 what="Description names differ !";
241 if(!areGrpsEqual(other,what))
243 if(!areFamsEqual(other,what))
248 void MEDFileMesh::setName(const std::string& name)
254 * Clears redundant attributes of incorporated data arrays.
256 void MEDFileMesh::clearNonDiscrAttributes() const
261 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
263 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
265 if((*it).first==_name)
275 * Copies data on groups and families from another mesh.
276 * \param [in] other - the mesh to copy the data from.
278 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
280 _groups=other._groups;
281 _families=other._families;
286 * This method clear all the groups in the map.
287 * So this method does not operate at all on arrays.
288 * So this method can lead to orphan families.
290 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
292 void MEDFileMesh::clearGrpMap()
298 * This method clear all the families in the map.
299 * So this method does not operate at all on arrays.
300 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
302 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
304 void MEDFileMesh::clearFamMap()
310 * This method clear all the families and groups in the map.
311 * So this method does not operate at all on arrays.
312 * As all groups and families entry will be removed after
313 * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object.
315 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
317 void MEDFileMesh::clearFamGrpMaps()
324 * Returns names of families constituting a group.
325 * \param [in] name - the name of the group of interest.
326 * \return std::vector<std::string> - a sequence of names of the families.
327 * \throw If the name of a nonexistent group is specified.
329 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
331 std::string oname(name);
332 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
333 if(it==_groups.end())
335 std::vector<std::string> grps=getGroupsNames();
336 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
337 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
338 throw INTERP_KERNEL::Exception(oss.str().c_str());
344 * Returns names of families constituting some groups.
345 * \param [in] grps - a sequence of names of groups of interest.
346 * \return std::vector<std::string> - a sequence of names of the families.
347 * \throw If a name of a nonexistent group is present in \a grps.
349 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
351 std::set<std::string> fams;
352 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
354 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
355 if(it2==_groups.end())
357 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
358 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
359 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
360 throw INTERP_KERNEL::Exception(oss.str().c_str());
362 fams.insert((*it2).second.begin(),(*it2).second.end());
364 std::vector<std::string> fams2(fams.begin(),fams.end());
369 * Returns ids of families constituting a group.
370 * \param [in] name - the name of the group of interest.
371 * \return std::vector<int> - sequence of ids of the families.
372 * \throw If the name of a nonexistent group is specified.
374 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
376 std::string oname(name);
377 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
378 std::vector<std::string> grps=getGroupsNames();
379 if(it==_groups.end())
381 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
382 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
383 throw INTERP_KERNEL::Exception(oss.str().c_str());
385 return getFamiliesIds((*it).second);
389 * Sets names of families constituting a group. If data on families of this group is
390 * already present, it is overwritten. Every family in \a fams is checked, and if a
391 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
392 * \param [in] name - the name of the group of interest.
393 * \param [in] fams - a sequence of names of families constituting the group.
395 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
397 std::string oname(name);
399 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
401 std::map<std::string,int>::iterator it2=_families.find(*it1);
402 if(it2==_families.end())
408 * Sets families constituting a group. The families are specified by their ids.
409 * If a family name is not found by its id, an exception is thrown.
410 * If several families have same id, the first one in lexical order is taken.
411 * \param [in] name - the name of the group of interest.
412 * \param [in] famIds - a sequence of ids of families constituting the group.
413 * \throw If a family name is not found by its id.
415 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
417 std::string oname(name);
418 std::vector<std::string> fams(famIds.size());
420 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
422 std::string name2=getFamilyNameGivenId(*it1);
429 * Returns names of groups including a given family.
430 * \param [in] name - the name of the family of interest.
431 * \return std::vector<std::string> - a sequence of names of groups including the family.
433 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
435 std::vector<std::string> ret;
436 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
438 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
441 ret.push_back((*it1).first);
449 * Adds an existing family to groups.
450 * \param [in] famName - a name of family to add to \a grps.
451 * \param [in] grps - a sequence of group names to add the family in.
452 * \throw If a family named \a famName not yet exists.
454 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
456 std::string fName(famName);
457 const std::map<std::string,int>::const_iterator it=_families.find(fName);
458 if(it==_families.end())
460 std::vector<std::string> fams=getFamiliesNames();
461 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
462 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
463 throw INTERP_KERNEL::Exception(oss.str().c_str());
465 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
467 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
468 if(it2!=_groups.end())
469 (*it2).second.push_back(fName);
472 std::vector<std::string> grps2(1,fName);
479 * Returns names of all groups of \a this mesh.
480 * \return std::vector<std::string> - a sequence of group names.
482 std::vector<std::string> MEDFileMesh::getGroupsNames() const
484 std::vector<std::string> ret(_groups.size());
486 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
492 * Returns names of all families of \a this mesh.
493 * \return std::vector<std::string> - a sequence of family names.
495 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
497 std::vector<std::string> ret(_families.size());
499 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
505 * Changes a name of every family, included in one group only, to be same as the group name.
506 * \throw If there are families with equal names in \a this mesh.
508 void MEDFileMesh::assignFamilyNameWithGroupName()
510 std::map<std::string, std::vector<std::string> > groups(_groups);
511 std::map<std::string,int> newFams;
512 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
514 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
515 if(grps.size()==1 && groups[grps[0]].size()==1)
517 if(newFams.find(grps[0])!=newFams.end())
519 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
520 throw INTERP_KERNEL::Exception(oss.str().c_str());
522 newFams[grps[0]]=(*it).second;
523 std::vector<std::string>& grps2=groups[grps[0]];
524 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
529 if(newFams.find((*it).first)!=newFams.end())
531 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
532 throw INTERP_KERNEL::Exception(oss.str().c_str());
534 newFams[(*it).first]=(*it).second;
542 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
544 * \return the removed groups.
546 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
548 std::vector<std::string> ret;
549 std::map<std::string, std::vector<std::string> > newGrps;
550 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
552 if((*it).second.empty())
553 ret.push_back((*it).first);
555 newGrps[(*it).first]=(*it).second;
563 * Removes a group from \a this mesh.
564 * \param [in] name - the name of the group to remove.
565 * \throw If no group with such a \a name exists.
567 void MEDFileMesh::removeGroup(const std::string& name)
569 std::string oname(name);
570 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
571 std::vector<std::string> grps=getGroupsNames();
572 if(it==_groups.end())
574 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
575 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
576 throw INTERP_KERNEL::Exception(oss.str().c_str());
582 * Removes a family from \a this mesh.
583 * \param [in] name - the name of the family to remove.
584 * \throw If no family with such a \a name exists.
586 void MEDFileMesh::removeFamily(const std::string& name)
588 std::string oname(name);
589 std::map<std::string, int >::iterator it=_families.find(oname);
590 std::vector<std::string> fams=getFamiliesNames();
591 if(it==_families.end())
593 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
594 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
595 throw INTERP_KERNEL::Exception(oss.str().c_str());
598 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
600 std::vector<std::string>& v=(*it3).second;
601 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
608 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
609 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
610 * family field whatever its level. This method also suppresses the orphan families.
612 * \return - The list of removed groups names.
614 * \sa MEDFileMesh::removeOrphanFamilies.
616 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
618 removeOrphanFamilies();
619 return removeEmptyGroups();
623 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
624 * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified.
626 * \return - The list of removed families names.
627 * \sa MEDFileMesh::removeOrphanGroups.
629 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
632 std::vector<std::string> ret;
633 if(!((DataArrayInt*)allFamIdsInUse))
635 ret=getFamiliesNames();
636 _families.clear(); _groups.clear();
639 std::map<std::string,int> famMap;
640 std::map<std::string, std::vector<std::string> > grps(_groups);
641 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
643 if(allFamIdsInUse->presenceOfValue((*it).second))
644 famMap[(*it).first]=(*it).second;
647 ret.push_back((*it).first);
648 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
649 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
651 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
652 std::vector<std::string>& famv=(*it3).second;
653 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
659 { _families=famMap; _groups=grps; }
664 * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever
665 * this family is orphan or not.
667 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
669 void MEDFileMesh::removeFamiliesReferedByNoGroups()
671 std::map<std::string,int> fams;
672 std::set<std::string> sfams;
673 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
674 sfams.insert((*it).first);
675 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
676 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
678 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
679 if(*it!=DFT_FAM_NAME)
680 _families.erase(*it);
684 * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities
685 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
686 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
688 * \sa MEDFileMesh::removeOrphanFamilies
690 void MEDFileMesh::rearrangeFamilies()
692 checkOrphanFamilyZero();
693 removeFamiliesReferedByNoGroups();
695 std::vector<int> levels(getNonEmptyLevelsExt());
696 std::set<int> idsRefed;
697 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
698 idsRefed.insert((*it).second);
699 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
701 const DataArrayInt *fams(0);
704 fams=getFamilyFieldAtLevel(*it);
706 catch(INTERP_KERNEL::Exception& e) { }
709 std::vector<bool> v(fams->getNumberOfTuples(),false);
710 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
711 fams->switchOnTupleEqualTo(*pt,v);
712 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
713 if(!unfetchedIds->empty())
715 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
716 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
717 setFamilyFieldArr(*it,newFams);
720 removeOrphanFamilies();
724 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
726 void MEDFileMesh::checkOrphanFamilyZero() const
728 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
730 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
732 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
733 throw INTERP_KERNEL::Exception(oss.str().c_str());
739 * Renames a group in \a this mesh.
740 * \param [in] oldName - a current name of the group to rename.
741 * \param [in] newName - a new group name.
742 * \throw If no group named \a oldName exists in \a this mesh.
743 * \throw If a group named \a newName already exists.
745 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
747 std::string oname(oldName);
748 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
749 std::vector<std::string> grps=getGroupsNames();
750 if(it==_groups.end())
752 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
753 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
754 throw INTERP_KERNEL::Exception(oss.str().c_str());
756 std::string nname(newName);
757 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
758 if(it2!=_groups.end())
760 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
761 throw INTERP_KERNEL::Exception(oss.str().c_str());
763 std::vector<std::string> cpy=(*it).second;
765 _groups[newName]=cpy;
769 * Changes an id of a family in \a this mesh.
770 * This method calls changeFamilyIdArr().
771 * \param [in] oldId - a current id of the family.
772 * \param [in] newId - a new family id.
774 void MEDFileMesh::changeFamilyId(int oldId, int newId)
776 changeFamilyIdArr(oldId,newId);
777 std::map<std::string,int> fam2;
778 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
780 if((*it).second==oldId)
781 fam2[(*it).first]=newId;
783 fam2[(*it).first]=(*it).second;
789 * Renames a family in \a this mesh.
790 * \param [in] oldName - a current name of the family to rename.
791 * \param [in] newName - a new family name.
792 * \throw If no family named \a oldName exists in \a this mesh.
793 * \throw If a family named \a newName already exists.
795 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
797 std::string oname(oldName);
798 std::map<std::string, int >::iterator it=_families.find(oname);
799 std::vector<std::string> fams=getFamiliesNames();
800 if(it==_families.end())
802 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
803 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
804 throw INTERP_KERNEL::Exception(oss.str().c_str());
806 std::string nname(newName);
807 std::map<std::string, int >::iterator it2=_families.find(nname);
808 if(it2!=_families.end())
810 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
811 throw INTERP_KERNEL::Exception(oss.str().c_str());
813 int cpy=(*it).second;
815 _families[newName]=cpy;
816 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
818 std::vector<std::string>& v=(*it3).second;
819 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
826 * Checks if \a this and another mesh contains the same families.
827 * \param [in] other - the mesh to compare with \a this one.
828 * \param [in,out] what - an unused parameter.
829 * \return bool - \c true if number of families and their ids are the same in the two
830 * meshes. Families with the id == \c 0 are not considered.
832 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
834 if(_families==other->_families)
836 std::map<std::string,int> fam0;
837 std::map<std::string,int> fam1;
838 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
840 fam0[(*it).first]=(*it).second;
841 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
843 fam1[(*it).first]=(*it).second;
848 * Checks if \a this and another mesh contains the same groups.
849 * \param [in] other - the mesh to compare with \a this one.
850 * \param [in,out] what - a string describing a difference of groups of the two meshes
851 * in case if this method returns \c false.
852 * \return bool - \c true if number of groups and families constituting them are the
853 * same in the two meshes.
855 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
857 if(_groups==other->_groups)
860 std::size_t sz=_groups.size();
861 if(sz!=other->_groups.size())
863 what="Groups differ because not same number !\n";
868 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
869 for(std::size_t i=0;i<sz && ret;i++,it1++)
871 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
872 if(it2!=other->_groups.end())
874 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
875 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
881 what="A group in first mesh exists not in other !\n";
887 std::ostringstream oss; oss << "Groups description differs :\n";
888 oss << "First group description :\n";
889 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
891 oss << " Group \"" << (*it).first << "\" on following families :\n";
892 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
893 oss << " \"" << *it2 << "\n";
895 oss << "Second group description :\n";
896 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
898 oss << " Group \"" << (*it).first << "\" on following families :\n";
899 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
900 oss << " \"" << *it2 << "\n";
908 * Checks if a group with a given name exists in \a this mesh.
909 * \param [in] groupName - the group name.
910 * \return bool - \c true the group \a groupName exists in \a this mesh.
912 bool MEDFileMesh::existsGroup(const std::string& groupName) const
914 std::string grpName(groupName);
915 return _groups.find(grpName)!=_groups.end();
919 * Checks if a family with a given id exists in \a this mesh.
920 * \param [in] famId - the family id.
921 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
923 bool MEDFileMesh::existsFamily(int famId) const
925 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
926 if((*it2).second==famId)
932 * Checks if a family with a given name exists in \a this mesh.
933 * \param [in] familyName - the family name.
934 * \return bool - \c true the family \a familyName exists in \a this mesh.
936 bool MEDFileMesh::existsFamily(const std::string& familyName) const
938 std::string fname(familyName);
939 return _families.find(fname)!=_families.end();
943 * Sets an id of a family.
944 * \param [in] familyName - the family name.
945 * \param [in] id - a new id of the family.
947 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
949 std::string fname(familyName);
953 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
955 std::string fname(familyName);
956 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
959 if((*it).first!=familyName)
961 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
962 throw INTERP_KERNEL::Exception(oss.str().c_str());
969 * Adds a family to \a this mesh.
970 * \param [in] familyName - a name of the family.
971 * \param [in] famId - an id of the family.
972 * \throw If a family with the same name or id already exists in \a this mesh.
974 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
976 std::string fname(familyName);
977 std::map<std::string,int>::const_iterator it=_families.find(fname);
978 if(it==_families.end())
980 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
981 if((*it2).second==famId)
983 std::ostringstream oss;
984 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
985 throw INTERP_KERNEL::Exception(oss.str().c_str());
987 _families[fname]=famId;
991 if((*it).second!=famId)
993 std::ostringstream oss;
994 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
995 throw INTERP_KERNEL::Exception(oss.str().c_str());
1001 * Creates a group including all mesh entities of given dimension.
1002 * \warning This method does \b not guarantee that the created group includes mesh
1003 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1004 * present in family fields of different dimensions. To assure this, call
1005 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1006 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1008 * \param [in] groupName - a name of the new group.
1009 * \throw If a group named \a groupName already exists.
1010 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1011 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1013 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1015 std::string grpName(groupName);
1016 std::vector<int> levs=getNonEmptyLevelsExt();
1017 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1019 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1020 oss << "Available relative ext levels are : ";
1021 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1022 throw INTERP_KERNEL::Exception(oss.str().c_str());
1024 if(existsGroup(groupName))
1026 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1027 oss << "Already existing groups are : ";
1028 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1029 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1030 throw INTERP_KERNEL::Exception(oss.str().c_str());
1032 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1034 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1035 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1036 std::vector<std::string> familiesOnWholeGroup;
1037 for(const int *it=famIds->begin();it!=famIds->end();it++)
1040 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1042 _groups[grpName]=familiesOnWholeGroup;
1046 * Ensures that given family ids do not present in family fields of dimensions different
1047 * than given ones. If a family id is present in the family fields of dimensions different
1048 * than the given ones, a new family is created and the whole data is updated accordingly.
1049 * \param [in] famIds - a sequence of family ids to check.
1050 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1051 * famIds should exclusively belong.
1052 * \return bool - \c true if no modification is done in \a this mesh by this method.
1054 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1056 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1057 std::vector<int> levs=getNonEmptyLevelsExt();
1058 std::set<int> levs2(levs.begin(),levs.end());
1059 std::vector<int> levsToTest;
1060 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1061 std::set<int> famIds2(famIds.begin(),famIds.end());
1064 if(!_families.empty())
1065 maxFamId=getMaxFamilyId()+1;
1066 std::vector<std::string> allFams=getFamiliesNames();
1067 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1069 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1072 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1073 std::vector<int> tmp;
1074 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1075 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1078 std::string famName=getFamilyNameGivenId(*it2);
1079 std::ostringstream oss; oss << "Family_" << maxFamId;
1080 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1081 addFamilyOnAllGroupsHaving(famName,zeName);
1082 _families[zeName]=maxFamId;
1083 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1092 * Adds a family to a given group in \a this mesh. If the group with a given name does
1093 * not exist, it is created.
1094 * \param [in] grpName - the name of the group to add the family in.
1095 * \param [in] famName - the name of the family to add to the group named \a grpName.
1096 * \throw If \a grpName or \a famName is an empty string.
1097 * \throw If no family named \a famName is present in \a this mesh.
1099 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1101 std::string grpn(grpName);
1102 std::string famn(famName);
1103 if(grpn.empty() || famn.empty())
1104 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1105 std::vector<std::string> fams=getFamiliesNames();
1106 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1108 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1109 oss << "Create this family or choose an existing one ! Existing fams are : ";
1110 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1111 throw INTERP_KERNEL::Exception(oss.str().c_str());
1113 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1114 if(it==_groups.end())
1116 _groups[grpn].push_back(famn);
1120 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1121 if(it2==(*it).second.end())
1122 (*it).second.push_back(famn);
1127 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1128 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1129 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1131 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1133 std::string famNameCpp(famName);
1134 std::string otherCpp(otherFamName);
1135 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1137 std::vector<std::string>& v=(*it).second;
1138 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1140 v.push_back(otherCpp);
1145 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1147 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1150 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1152 std::string fam(familyNameToChange);
1153 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1155 std::vector<std::string>& fams((*it).second);
1156 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1160 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1166 * Returns a name of the family having a given id or, if no such a family exists, creates
1167 * a new uniquely named family and returns its name.
1168 * \param [in] id - the id of the family whose name is required.
1169 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1170 * \return std::string - the name of the existing or the created family.
1171 * \throw If it is not possible to create a unique family name.
1173 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1175 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1179 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1180 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1181 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1182 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1184 * This method will throws an exception if it is not possible to create a unique family name.
1186 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1188 std::vector<std::string> famAlreadyExisting(families.size());
1190 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1192 if((*it).second!=id)
1194 famAlreadyExisting[ii]=(*it).first;
1203 std::ostringstream oss; oss << "Family_" << id;
1204 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1210 * Sets names and ids of all families in \a this mesh.
1211 * \param [in] info - a map of a family name to a family id.
1213 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1219 * Sets names of all groups and families constituting them in \a this mesh.
1220 * \param [in] info - a map of a group name to a vector of names of families
1221 * constituting the group.
1223 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1229 * Returns an id of the family having a given name.
1230 * \param [in] name - the name of the family of interest.
1231 * \return int - the id of the family of interest.
1232 * \throw If no family with such a \a name exists.
1234 int MEDFileMesh::getFamilyId(const std::string& name) const
1236 std::string oname(name);
1237 std::map<std::string, int>::const_iterator it=_families.find(oname);
1238 std::vector<std::string> fams=getFamiliesNames();
1239 if(it==_families.end())
1241 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1242 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1243 throw INTERP_KERNEL::Exception(oss.str().c_str());
1245 return (*it).second;
1249 * Returns ids of the families having given names.
1250 * \param [in] fams - a sequence of the names of families of interest.
1251 * \return std::vector<int> - a sequence of the ids of families of interest.
1252 * \throw If \a fams contains a name of an inexistent family.
1254 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1256 std::vector<int> ret(fams.size());
1258 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1260 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1261 if(it2==_families.end())
1263 std::vector<std::string> fams2=getFamiliesNames();
1264 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1265 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1266 throw INTERP_KERNEL::Exception(oss.str().c_str());
1268 ret[i]=(*it2).second;
1274 * Returns a maximal abs(id) of families in \a this mesh.
1275 * \return int - the maximal norm of family id.
1276 * \throw If there are no families in \a this mesh.
1278 int MEDFileMesh::getMaxAbsFamilyId() const
1280 if(_families.empty())
1281 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1282 int ret=-std::numeric_limits<int>::max();
1283 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1285 ret=std::max(std::abs((*it).second),ret);
1291 * Returns a maximal id of families in \a this mesh.
1292 * \return int - the maximal family id.
1293 * \throw If there are no families in \a this mesh.
1295 int MEDFileMesh::getMaxFamilyId() const
1297 if(_families.empty())
1298 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1299 int ret=-std::numeric_limits<int>::max();
1300 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1302 ret=std::max((*it).second,ret);
1308 * Returns a minimal id of families in \a this mesh.
1309 * \return int - the minimal family id.
1310 * \throw If there are no families in \a this mesh.
1312 int MEDFileMesh::getMinFamilyId() const
1314 if(_families.empty())
1315 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1316 int ret=std::numeric_limits<int>::max();
1317 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1319 ret=std::min((*it).second,ret);
1325 * Returns a maximal id of families in \a this mesh. Not only named families are
1326 * considered but all family fields as well.
1327 * \return int - the maximal family id.
1329 int MEDFileMesh::getTheMaxAbsFamilyId() const
1331 int m1=-std::numeric_limits<int>::max();
1332 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1333 m1=std::max(std::abs((*it).second),m1);
1334 int m2=getMaxAbsFamilyIdInArrays();
1335 return std::max(m1,m2);
1339 * Returns a maximal id of families in \a this mesh. Not only named families are
1340 * considered but all family fields as well.
1341 * \return int - the maximal family id.
1343 int MEDFileMesh::getTheMaxFamilyId() const
1345 int m1=-std::numeric_limits<int>::max();
1346 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1347 m1=std::max((*it).second,m1);
1348 int m2=getMaxFamilyIdInArrays();
1349 return std::max(m1,m2);
1353 * Returns a minimal id of families in \a this mesh. Not only named families are
1354 * considered but all family fields as well.
1355 * \return int - the minimal family id.
1357 int MEDFileMesh::getTheMinFamilyId() const
1359 int m1=std::numeric_limits<int>::max();
1360 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1361 m1=std::min((*it).second,m1);
1362 int m2=getMinFamilyIdInArrays();
1363 return std::min(m1,m2);
1367 * This method only considers the maps. The contain of family array is ignored here.
1369 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1371 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1373 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1375 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1376 v.insert((*it).second);
1377 ret->alloc((int)v.size(),1);
1378 std::copy(v.begin(),v.end(),ret->getPointer());
1383 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1385 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1387 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1389 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1390 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1391 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1393 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1394 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1395 if((DataArrayInt *) ret)
1396 ret=dv->buildUnion(ret);
1404 * true is returned if no modification has been needed. false if family
1405 * renumbering has been needed.
1407 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1409 std::vector<int> levs=getNonEmptyLevelsExt();
1410 std::set<int> allFamIds;
1411 int maxId=getMaxFamilyId()+1;
1412 std::map<int,std::vector<int> > famIdsToRenum;
1413 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1415 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1418 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1420 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1422 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1424 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1427 if(famIdsToRenum.empty())
1429 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1430 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1432 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1433 int *famIdsToChange=fam->getPointer();
1434 std::map<int,int> ren;
1435 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1437 if(allIds->presenceOfValue(*it3))
1439 std::string famName=getFamilyNameGivenId(*it3);
1440 std::vector<std::string> grps=getGroupsOnFamily(famName);
1443 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1444 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1445 addFamilyOnGrp((*it4),newFam);
1448 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1449 for(const int *id=ids->begin();id!=ids->end();id++)
1450 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1456 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1457 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1458 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1459 * This method will throw an exception if a same family id is detected in different level.
1460 * \warning This policy is the opposite of those in MED file documentation ...
1462 void MEDFileMesh::normalizeFamIdsTrio()
1464 ensureDifferentFamIdsPerLevel();
1465 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1466 std::vector<int> levs=getNonEmptyLevelsExt();
1467 std::set<int> levsS(levs.begin(),levs.end());
1468 std::set<std::string> famsFetched;
1469 std::map<std::string,int> families;
1470 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1473 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1477 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1478 std::map<int,int> ren;
1479 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1481 int nbOfTuples=fam->getNumberOfTuples();
1482 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1483 for(int *w=start;w!=start+nbOfTuples;w++)
1485 for(const int *it=tmp->begin();it!=tmp->end();it++)
1487 if(allIds->presenceOfValue(*it))
1489 std::string famName=getFamilyNameGivenId(*it);
1490 families[famName]=ren[*it];
1491 famsFetched.insert(famName);
1496 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1499 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1503 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1504 std::map<int,int> ren;
1505 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1507 int nbOfTuples=fam->getNumberOfTuples();
1508 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1509 for(int *w=start;w!=start+nbOfTuples;w++)
1511 for(const int *it=tmp->begin();it!=tmp->end();it++)
1513 if(allIds->presenceOfValue(*it))
1515 std::string famName=getFamilyNameGivenId(*it);
1516 families[famName]=ren[*it];
1517 famsFetched.insert(famName);
1522 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1524 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1527 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1528 fam->fillWithZero();
1529 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1530 if(allIds->presenceOfValue(*it3))
1532 std::string famName=getFamilyNameGivenId(*it3);
1533 families[famName]=0;
1534 famsFetched.insert(famName);
1539 std::vector<std::string> allFams=getFamiliesNames();
1540 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1541 std::set<std::string> unFetchedIds;
1542 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1543 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1544 families[*it4]=_families[*it4];
1549 * This method normalizes fam id with the following policy.
1550 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1551 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1552 * This method will throw an exception if a same family id is detected in different level.
1554 void MEDFileMesh::normalizeFamIdsMEDFile()
1556 ensureDifferentFamIdsPerLevel();
1557 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1558 std::vector<int> levs=getNonEmptyLevelsExt();
1559 std::set<int> levsS(levs.begin(),levs.end());
1560 std::set<std::string> famsFetched;
1561 std::map<std::string,int> families;
1563 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1566 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1569 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1570 std::map<int,int> ren;
1571 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1573 int nbOfTuples=fam->getNumberOfTuples();
1574 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1575 for(int *w=start;w!=start+nbOfTuples;w++)
1577 for(const int *it=tmp->begin();it!=tmp->end();it++)
1579 if(allIds->presenceOfValue(*it))
1581 std::string famName=getFamilyNameGivenId(*it);
1582 families[famName]=ren[*it];
1583 famsFetched.insert(famName);
1589 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1591 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1594 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1595 std::map<int,int> ren;
1596 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1598 int nbOfTuples=fam->getNumberOfTuples();
1599 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1600 for(int *w=start;w!=start+nbOfTuples;w++)
1602 for(const int *it=tmp->begin();it!=tmp->end();it++)
1604 if(allIds->presenceOfValue(*it))
1606 std::string famName=getFamilyNameGivenId(*it);
1607 families[famName]=ren[*it];
1608 famsFetched.insert(famName);
1614 std::vector<std::string> allFams=getFamiliesNames();
1615 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1616 std::set<std::string> unFetchedIds;
1617 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1618 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1619 families[*it4]=_families[*it4];
1624 * Returns a name of the family by its id. If there are several families having the given
1625 * id, the name first in lexical order is returned.
1626 * \param [in] id - the id of the family whose name is required.
1627 * \return std::string - the name of the found family.
1628 * \throw If no family with the given \a id exists.
1630 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1632 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1633 if((*it).second==id)
1635 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1636 throw INTERP_KERNEL::Exception(oss.str().c_str());
1640 * Returns a string describing \a this mesh. This description includes the mesh name and
1641 * the mesh description string.
1642 * \return std::string - the mesh information string.
1644 std::string MEDFileMesh::simpleRepr() const
1646 std::ostringstream oss;
1647 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1648 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1649 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1654 * Returns ids of mesh entities contained in a given group of a given dimension.
1655 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1657 * \param [in] grp - the name of the group of interest.
1658 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1659 * returned instead of ids.
1660 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1661 * numbers, if available and required, of mesh entities of the group. The caller
1662 * is to delete this array using decrRef() as it is no more needed.
1663 * \throw If the name of a nonexistent group is specified.
1664 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1666 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1668 std::vector<std::string> tmp(1);
1670 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1676 * Returns ids of mesh entities contained in given groups of a given dimension.
1677 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1679 * \param [in] grps - the names of the groups of interest.
1680 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1681 * returned instead of ids.
1682 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1683 * numbers, if available and required, of mesh entities of the groups. The caller
1684 * is to delete this array using decrRef() as it is no more needed.
1685 * \throw If the name of a nonexistent group is present in \a grps.
1686 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1688 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1690 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1691 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1695 * Returns ids of mesh entities contained in a given family of a given dimension.
1696 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1698 * \param [in] fam - the name of the family of interest.
1699 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1700 * returned instead of ids.
1701 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1702 * numbers, if available and required, of mesh entities of the family. The caller
1703 * is to delete this array using decrRef() as it is no more needed.
1704 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1706 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1708 std::vector<std::string> tmp(1);
1710 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1716 * Returns ids of nodes contained in a given group.
1717 * \param [in] grp - the name of the group of interest.
1718 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1719 * returned instead of ids.
1720 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1721 * numbers, if available and required, of nodes of the group. The caller
1722 * is to delete this array using decrRef() as it is no more needed.
1723 * \throw If the name of a nonexistent group is specified.
1724 * \throw If the family field is missing for nodes.
1726 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1728 std::vector<std::string> tmp(1);
1730 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1736 * Returns ids of nodes contained in given groups.
1737 * \param [in] grps - the names of the groups of interest.
1738 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1739 * returned instead of ids.
1740 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1741 * numbers, if available and required, of nodes of the groups. The caller
1742 * is to delete this array using decrRef() as it is no more needed.
1743 * \throw If the name of a nonexistent group is present in \a grps.
1744 * \throw If the family field is missing for nodes.
1746 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1748 return getGroupsArr(1,grps,renum);
1752 * Returns ids of nodes contained in a given group.
1753 * \param [in] grp - the name of the group of interest.
1754 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1755 * returned instead of ids.
1756 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1757 * numbers, if available and required, of nodes of the group. The caller
1758 * is to delete this array using decrRef() as it is no more needed.
1759 * \throw If the name of a nonexistent group is specified.
1760 * \throw If the family field is missing for nodes.
1762 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1764 std::vector<std::string> tmp(1);
1766 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1772 * Returns ids of nodes contained in given families.
1773 * \param [in] fams - the names of the families of interest.
1774 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1775 * returned instead of ids.
1776 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1777 * numbers, if available and required, of nodes of the families. The caller
1778 * is to delete this array using decrRef() as it is no more needed.
1779 * \throw If the family field is missing for nodes.
1781 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1783 return getFamiliesArr(1,fams,renum);
1787 * Adds groups of given dimension and creates corresponding families and family fields
1788 * given ids of mesh entities of each group.
1789 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1790 * \param [in] grps - a sequence of arrays of ids each describing a group.
1791 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1793 * \throw If names of some groups in \a grps are equal.
1794 * \throw If \a grps includes a group with an empty name.
1795 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1796 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1798 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1802 std::set<std::string> grpsName;
1803 std::vector<std::string> grpsName2(grps.size());
1806 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1808 grpsName.insert((*it)->getName());
1809 grpsName2[i]=(*it)->getName();
1811 if(grpsName.size()!=grps.size())
1812 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1813 if(grpsName.find(std::string(""))!=grpsName.end())
1814 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1815 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1816 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1817 std::vector< std::vector<int> > fidsOfGroups;
1820 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1824 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1825 for(unsigned int ii=0;ii<grps.size();ii++)
1827 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1828 grps2[ii]->setName(grps[ii]->getName());
1830 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1831 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1834 if(!_families.empty())
1835 offset=getMaxAbsFamilyId()+1;
1836 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1837 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1838 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1839 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1843 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1844 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1845 * For the moment, the two last input parameters are not taken into account.
1847 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1849 std::map<int,std::string> famInv;
1850 for(const int *it=famIds->begin();it!=famIds->end();it++)
1852 std::ostringstream oss;
1853 oss << "Family_" << (*it);
1854 _families[oss.str()]=(*it);
1855 famInv[*it]=oss.str();
1858 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1860 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1862 _groups[grpNames[i]].push_back(famInv[*it2]);
1867 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1869 std::vector<int> levs(getNonEmptyLevels());
1870 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1871 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1873 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1874 ret.insert(ret.end(),elts.begin(),elts.end());
1879 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1881 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1882 return mLev->getDistributionOfTypes();
1885 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1887 famArr->applyLin(offset>0?1:-1,offset,0);
1888 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1891 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1892 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1897 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1898 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1899 * If this method fails to find such a name it will throw an exception.
1901 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1904 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1907 std::size_t len=nameTry.length();
1908 for(std::size_t ii=1;ii<len;ii++)
1910 std::string tmp=nameTry.substr(ii,len-ii);
1911 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1917 for(std::size_t i=1;i<30;i++)
1919 std::string tmp1(nameTry.at(0),i);
1921 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1927 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1929 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1931 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1934 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
1936 std::size_t nbOfChunks=code.size()/3;
1937 if(code.size()%3!=0)
1938 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1940 for(std::size_t i=0;i<nbOfChunks;i++)
1949 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1950 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1951 * If _name is not empty and that 'm' has the same name nothing is done.
1952 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1954 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
1957 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1962 std::string name(m->getName());
1967 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1968 oss << name << "' ! Names must match !";
1969 throw INTERP_KERNEL::Exception(oss.str().c_str());
1973 if(_desc_name.empty())
1974 _desc_name=m->getDescription();
1977 std::string name(m->getDescription());
1980 if(_desc_name!=name)
1982 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1983 oss << name << "' ! Names must match !";
1984 throw INTERP_KERNEL::Exception(oss.str().c_str());
1990 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1992 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1993 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1995 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1996 oss << " - Groups lying on this family : ";
1997 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
1998 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1999 oss << std::endl << std::endl;
2004 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2005 * file. The mesh to load is specified by its name and numbers of a time step and an
2007 * \param [in] fileName - the name of MED file to read.
2008 * \param [in] mName - the name of the mesh to read.
2009 * \param [in] dt - the number of a time step.
2010 * \param [in] it - the number of an iteration.
2011 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2012 * mesh using decrRef() as it is no more needed.
2013 * \throw If the file is not readable.
2014 * \throw If there is no mesh with given attributes in the file.
2015 * \throw If the mesh in the file is not an unstructured one.
2017 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2019 MEDFileUtilities::CheckFileForRead(fileName);
2020 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2021 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2025 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2026 * file. The first mesh in the file is loaded.
2027 * \param [in] fileName - the name of MED file to read.
2028 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2029 * mesh using decrRef() as it is no more needed.
2030 * \throw If the file is not readable.
2031 * \throw If there is no meshes in the file.
2032 * \throw If the mesh in the file is not an unstructured one.
2034 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2036 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2039 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2040 throw INTERP_KERNEL::Exception(oss.str().c_str());
2042 MEDFileUtilities::CheckFileForRead(fileName);
2043 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2045 ParaMEDMEM::MEDCouplingMeshType meshType;
2047 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
2048 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2052 * Returns an empty instance of MEDFileUMesh.
2053 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2054 * mesh using decrRef() as it is no more needed.
2056 MEDFileUMesh *MEDFileUMesh::New()
2058 return new MEDFileUMesh;
2062 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2063 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2064 * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh.
2065 * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce
2066 * at most the memory consumtion.
2068 * \param [in] fileName - the name of the file.
2069 * \param [in] mName - the name of the mesh to be read.
2070 * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
2071 * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
2072 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2073 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2074 * \param [in] mrs - the request for what to be loaded.
2075 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2077 MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2079 MEDFileUtilities::CheckFileForRead(fileName);
2080 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2081 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2085 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2086 * This method is \b NOT wrapped into python.
2088 MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2090 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2091 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2095 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2097 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2098 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2102 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2104 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2105 ret.push_back((const DataArrayDouble*)_coords);
2106 ret.push_back((const DataArrayInt *)_fam_coords);
2107 ret.push_back((const DataArrayInt *)_num_coords);
2108 ret.push_back((const DataArrayInt *)_rev_num_coords);
2109 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2110 ret.push_back((const PartDefinition *)_part_coords);
2111 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2112 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2116 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2118 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2122 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2124 return new MEDFileUMesh;
2127 MEDFileMesh *MEDFileUMesh::deepCpy() const
2129 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2130 if((const DataArrayDouble*)_coords)
2131 ret->_coords=_coords->deepCpy();
2132 if((const DataArrayInt*)_fam_coords)
2133 ret->_fam_coords=_fam_coords->deepCpy();
2134 if((const DataArrayInt*)_num_coords)
2135 ret->_num_coords=_num_coords->deepCpy();
2136 if((const DataArrayInt*)_rev_num_coords)
2137 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2138 if((const DataArrayAsciiChar*)_name_coords)
2139 ret->_name_coords=_name_coords->deepCpy();
2141 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2143 if((const MEDFileUMeshSplitL1 *)(*it))
2144 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2146 if((const PartDefinition*)_part_coords)
2147 ret->_part_coords=_part_coords->deepCpy();
2152 * Checks if \a this and another mesh are equal.
2153 * \param [in] other - the mesh to compare with.
2154 * \param [in] eps - a precision used to compare real values.
2155 * \param [in,out] what - the string returning description of unequal data.
2156 * \return bool - \c true if the meshes are equal, \c false, else.
2158 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2160 if(!MEDFileMesh::isEqual(other,eps,what))
2162 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2165 what="Mesh types differ ! This is unstructured and other is NOT !";
2168 clearNonDiscrAttributes();
2169 otherC->clearNonDiscrAttributes();
2170 const DataArrayDouble *coo1=_coords;
2171 const DataArrayDouble *coo2=otherC->_coords;
2172 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2174 what="Mismatch of coordinates ! One is defined and not other !";
2179 bool ret=coo1->isEqual(*coo2,eps);
2182 what="Coords differ !";
2186 const DataArrayInt *famc1=_fam_coords;
2187 const DataArrayInt *famc2=otherC->_fam_coords;
2188 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2190 what="Mismatch of families arr on nodes ! One is defined and not other !";
2195 bool ret=famc1->isEqual(*famc2);
2198 what="Families arr on node differ !";
2202 const DataArrayInt *numc1=_num_coords;
2203 const DataArrayInt *numc2=otherC->_num_coords;
2204 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2206 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2211 bool ret=numc1->isEqual(*numc2);
2214 what="Numbering arr on node differ !";
2218 const DataArrayAsciiChar *namec1=_name_coords;
2219 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2220 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2222 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2227 bool ret=namec1->isEqual(*namec2);
2230 what="Names arr on node differ !";
2234 if(_ms.size()!=otherC->_ms.size())
2236 what="Number of levels differs !";
2239 std::size_t sz=_ms.size();
2240 for(std::size_t i=0;i<sz;i++)
2242 const MEDFileUMeshSplitL1 *s1=_ms[i];
2243 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2244 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2246 what="Mismatch of presence of sub levels !";
2251 bool ret=s1->isEqual(s2,eps,what);
2256 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2259 if((!pd0 && pd1) || (pd0 && !pd1))
2261 what=std::string("node part def is defined only for one among this or other !");
2264 return pd0->isEqual(pd1,what);
2268 * Clears redundant attributes of incorporated data arrays.
2270 void MEDFileUMesh::clearNonDiscrAttributes() const
2272 MEDFileMesh::clearNonDiscrAttributes();
2273 const DataArrayDouble *coo1=_coords;
2275 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2276 const DataArrayInt *famc1=_fam_coords;
2278 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2279 const DataArrayInt *numc1=_num_coords;
2281 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2282 const DataArrayAsciiChar *namc1=_name_coords;
2284 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2285 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2287 const MEDFileUMeshSplitL1 *tmp=(*it);
2289 tmp->clearNonDiscrAttributes();
2293 void MEDFileUMesh::setName(const std::string& name)
2295 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2296 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2297 (*it)->setName(name);
2298 MEDFileMesh::setName(name);
2301 MEDFileUMesh::MEDFileUMesh()
2305 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2308 loadUMeshFromFile(fid,mName,dt,it,mrs);
2310 catch(INTERP_KERNEL::Exception& e)
2316 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2317 * See MEDFileUMesh::LoadPartOf for detailed description.
2319 * \sa loadUMeshFromFile
2321 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2323 MEDFileUMeshL2 loaderl2;
2324 ParaMEDMEM::MEDCouplingMeshType meshType;
2327 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2328 if(meshType!=UNSTRUCTURED)
2330 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2331 throw INTERP_KERNEL::Exception(oss.str().c_str());
2333 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2334 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2338 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2340 * \sa loadPartUMeshFromFile
2342 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2344 MEDFileUMeshL2 loaderl2;
2345 ParaMEDMEM::MEDCouplingMeshType meshType;
2348 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2349 if(meshType!=UNSTRUCTURED)
2351 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2352 throw INTERP_KERNEL::Exception(oss.str().c_str());
2354 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2355 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2359 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2361 int lev=loaderl2.getNumberOfLevels();
2363 for(int i=0;i<lev;i++)
2365 if(!loaderl2.emptyLev(i))
2366 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2370 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2372 setName(loaderl2.getName());
2373 setDescription(loaderl2.getDescription());
2374 setUnivName(loaderl2.getUnivName());
2375 setIteration(loaderl2.getIteration());
2376 setOrder(loaderl2.getOrder());
2377 setTimeValue(loaderl2.getTime());
2378 setTimeUnit(loaderl2.getTimeUnit());
2379 _coords=loaderl2.getCoords();
2380 if(!mrs || mrs->isNodeFamilyFieldReading())
2381 _fam_coords=loaderl2.getCoordsFamily();
2382 if(!mrs || mrs->isNodeNumFieldReading())
2383 _num_coords=loaderl2.getCoordsNum();
2384 if(!mrs || mrs->isNodeNameFieldReading())
2385 _name_coords=loaderl2.getCoordsName();
2386 _part_coords=loaderl2.getPartDefOfCoo();
2390 MEDFileUMesh::~MEDFileUMesh()
2394 void MEDFileUMesh::writeLL(med_idt fid) const
2396 const DataArrayDouble *coo=_coords;
2397 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2398 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2399 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2400 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2401 int spaceDim=coo?coo->getNumberOfComponents():0;
2404 mdim=getMeshDimension();
2405 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2406 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2407 for(int i=0;i<spaceDim;i++)
2409 std::string info=coo->getInfoOnComponent(i);
2411 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2412 MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2413 MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2415 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2416 MEDmeshUniversalNameWr(fid,maa);
2417 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2418 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2419 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2420 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2421 (*it)->write(fid,meshName,mdim);
2422 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2426 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2427 * \return std::vector<int> - a sequence of the relative dimensions.
2429 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2431 std::vector<int> ret;
2433 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2434 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2441 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2442 * \return std::vector<int> - a sequence of the relative dimensions.
2444 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2446 std::vector<int> ret0=getNonEmptyLevels();
2447 if((const DataArrayDouble *) _coords)
2449 std::vector<int> ret(ret0.size()+1);
2451 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2457 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2459 std::vector<int> ret;
2460 const DataArrayInt *famCoo(_fam_coords);
2464 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2466 const MEDFileUMeshSplitL1 *cur(*it);
2468 if(cur->getFamilyField())
2474 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2476 std::vector<int> ret;
2477 const DataArrayInt *numCoo(_num_coords);
2481 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2483 const MEDFileUMeshSplitL1 *cur(*it);
2485 if(cur->getNumberField())
2491 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2493 std::vector<int> ret;
2494 const DataArrayAsciiChar *nameCoo(_name_coords);
2498 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2500 const MEDFileUMeshSplitL1 *cur(*it);
2502 if(cur->getNameField())
2509 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2510 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2511 * \param [in] grp - the name of the group of interest.
2512 * \return std::vector<int> - a sequence of the relative dimensions.
2514 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2516 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2517 return getFamsNonEmptyLevels(fams);
2521 * Returns all relative mesh levels (including nodes) where a given group is defined.
2522 * \param [in] grp - the name of the group of interest.
2523 * \return std::vector<int> - a sequence of the relative dimensions.
2525 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2527 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2528 return getFamsNonEmptyLevelsExt(fams);
2532 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2533 * To include nodes, call getFamNonEmptyLevelsExt() method.
2534 * \param [in] fam - the name of the family of interest.
2535 * \return std::vector<int> - a sequence of the relative dimensions.
2537 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2539 std::vector<std::string> fams(1,std::string(fam));
2540 return getFamsNonEmptyLevels(fams);
2544 * Returns all relative mesh levels (including nodes) where a given family is defined.
2545 * \param [in] fam - the name of the family of interest.
2546 * \return std::vector<int> - a sequence of the relative dimensions.
2548 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2550 std::vector<std::string> fams(1,std::string(fam));
2551 return getFamsNonEmptyLevelsExt(fams);
2555 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2556 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2557 * \param [in] grps - a sequence of names of the groups of interest.
2558 * \return std::vector<int> - a sequence of the relative dimensions.
2560 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2562 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2563 return getFamsNonEmptyLevels(fams);
2567 * Returns all relative mesh levels (including nodes) where given groups are defined.
2568 * \param [in] grps - a sequence of names of the groups of interest.
2569 * \return std::vector<int> - a sequence of the relative dimensions.
2571 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2573 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2574 return getFamsNonEmptyLevelsExt(fams);
2578 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2579 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2580 * \param [in] fams - the name of the family of interest.
2581 * \return std::vector<int> - a sequence of the relative dimensions.
2583 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2585 std::vector<int> ret;
2586 std::vector<int> levs=getNonEmptyLevels();
2587 std::vector<int> famIds=getFamiliesIds(fams);
2588 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2589 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2595 * Returns all relative mesh levels (including nodes) where given families are defined.
2596 * \param [in] fams - the names of the families of interest.
2597 * \return std::vector<int> - a sequence of the relative dimensions.
2599 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2601 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2602 const DataArrayInt *famCoords=_fam_coords;
2605 std::vector<int> famIds=getFamiliesIds(fams);
2606 if(famCoords->presenceOfValue(famIds))
2608 std::vector<int> ret(ret0.size()+1);
2610 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2618 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2619 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2620 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2623 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2625 std::vector<std::string> ret;
2626 std::vector<std::string> allGrps=getGroupsNames();
2627 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2629 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2630 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2636 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2638 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2639 if((const DataArrayInt *)_fam_coords)
2641 int val=_fam_coords->getMaxValue(tmp);
2642 ret=std::max(ret,std::abs(val));
2644 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2646 if((const MEDFileUMeshSplitL1 *)(*it))
2648 const DataArrayInt *da=(*it)->getFamilyField();
2651 int val=da->getMaxValue(tmp);
2652 ret=std::max(ret,std::abs(val));
2659 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2661 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2662 if((const DataArrayInt *)_fam_coords)
2664 int val=_fam_coords->getMaxValue(tmp);
2665 ret=std::max(ret,val);
2667 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2669 if((const MEDFileUMeshSplitL1 *)(*it))
2671 const DataArrayInt *da=(*it)->getFamilyField();
2674 int val=da->getMaxValue(tmp);
2675 ret=std::max(ret,val);
2682 int MEDFileUMesh::getMinFamilyIdInArrays() const
2684 int ret=std::numeric_limits<int>::max(),tmp=-1;
2685 if((const DataArrayInt *)_fam_coords)
2687 int val=_fam_coords->getMinValue(tmp);
2688 ret=std::min(ret,val);
2690 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2692 if((const MEDFileUMeshSplitL1 *)(*it))
2694 const DataArrayInt *da=(*it)->getFamilyField();
2697 int val=da->getMinValue(tmp);
2698 ret=std::min(ret,val);
2706 * Returns the dimension on cells in \a this mesh.
2707 * \return int - the mesh dimension.
2708 * \throw If there are no cells in this mesh.
2710 int MEDFileUMesh::getMeshDimension() const
2713 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2714 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2715 return (*it)->getMeshDimension()+lev;
2716 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2720 * Returns the space dimension of \a this mesh that is equal to number of components in
2721 * the node coordinates array.
2722 * \return int - the space dimension of \a this mesh.
2723 * \throw If the node coordinates array is not available.
2725 int MEDFileUMesh::getSpaceDimension() const
2727 const DataArrayDouble *coo=_coords;
2729 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2730 return coo->getNumberOfComponents();
2734 * Returns a string describing \a this mesh.
2735 * \return std::string - the mesh information string.
2737 std::string MEDFileUMesh::simpleRepr() const
2739 std::ostringstream oss;
2740 oss << MEDFileMesh::simpleRepr();
2741 const DataArrayDouble *coo=_coords;
2742 oss << "- The dimension of the space is ";
2743 static const char MSG1[]= "*** NO COORDS SET ***";
2744 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2746 oss << _coords->getNumberOfComponents() << std::endl;
2748 oss << MSG1 << std::endl;
2749 oss << "- Type of the mesh : UNSTRUCTURED\n";
2750 oss << "- Number of nodes : ";
2752 oss << _coords->getNumberOfTuples() << std::endl;
2754 oss << MSG1 << std::endl;
2755 std::size_t nbOfLev=_ms.size();
2756 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2757 for(std::size_t i=0;i<nbOfLev;i++)
2759 const MEDFileUMeshSplitL1 *lev=_ms[i];
2760 oss << " - Level #" << -((int) i) << " has dimension : ";
2763 oss << lev->getMeshDimension() << std::endl;
2764 lev->simpleRepr(oss);
2767 oss << MSG2 << std::endl;
2769 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2772 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2773 oss << "- Names of coordinates :" << std::endl;
2774 std::vector<std::string> vars=coo->getVarsOnComponent();
2775 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2776 oss << std::endl << "- Units of coordinates : " << std::endl;
2777 std::vector<std::string> units=coo->getUnitsOnComponent();
2778 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2780 oss << std::endl << std::endl;
2786 * Returns a full textual description of \a this mesh.
2787 * \return std::string - the string holding the mesh description.
2789 std::string MEDFileUMesh::advancedRepr() const
2791 return simpleRepr();
2795 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2796 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2797 * \return int - the number of entities.
2798 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2800 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2802 if(meshDimRelToMaxExt==1)
2804 if(!((const DataArrayDouble *)_coords))
2805 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2806 return _coords->getNumberOfTuples();
2808 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2812 * Returns the family field for mesh entities of a given dimension.
2813 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2814 * \return const DataArrayInt * - the family field. It is an array of ids of families
2815 * each mesh entity belongs to. It can be \c NULL.
2817 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2819 if(meshDimRelToMaxExt==1)
2821 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2822 return l1->getFamilyField();
2826 * Returns the optional numbers of mesh entities of a given dimension.
2827 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2828 * \return const DataArrayInt * - the array of the entity numbers.
2829 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2831 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2833 if(meshDimRelToMaxExt==1)
2835 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2836 return l1->getNumberField();
2839 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2841 if(meshDimRelToMaxExt==1)
2842 return _name_coords;
2843 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2844 return l1->getNameField();
2848 * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file).
2850 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
2851 * \param [in] gt - The input geometric type for which the part definition is requested.
2852 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
2854 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
2856 if(meshDimRelToMaxExt==1)
2857 return _part_coords;
2858 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2859 return l1->getPartDef(gt);
2862 int MEDFileUMesh::getNumberOfNodes() const
2864 const DataArrayDouble *coo=_coords;
2866 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2867 return coo->getNumberOfTuples();
2870 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
2872 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2873 return l1->getNumberOfCells();
2876 bool MEDFileUMesh::hasImplicitPart() const
2881 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
2883 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
2886 void MEDFileUMesh::releaseImplicitPartIfAny() const
2890 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2892 std::size_t sz(st.getNumberOfItems());
2893 for(std::size_t i=0;i<sz;i++)
2895 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2896 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2897 if(st[i].getPflName().empty())
2898 m->computeNodeIdsAlg(nodesFetched);
2901 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2902 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2903 m2->computeNodeIdsAlg(nodesFetched);
2909 * Returns the optional numbers of mesh entities of a given dimension transformed using
2910 * DataArrayInt::invertArrayN2O2O2N().
2911 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2912 * \return const DataArrayInt * - the array of the entity numbers transformed using
2913 * DataArrayInt::invertArrayN2O2O2N().
2914 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2916 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2918 if(meshDimRelToMaxExt==1)
2920 if(!((const DataArrayInt *)_num_coords))
2921 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2922 return _rev_num_coords;
2924 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2925 return l1->getRevNumberField();
2929 * Returns a pointer to the node coordinates array of \a this mesh \b without
2930 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2932 DataArrayDouble *MEDFileUMesh::getCoords() const
2934 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2935 if((DataArrayDouble *)tmp)
2943 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2944 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2946 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2947 * \param [in] grp - the name of the group whose mesh entities are included in the
2949 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2950 * according to the optional numbers of entities, if available.
2951 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2952 * delete this mesh using decrRef() as it is no more needed.
2953 * \throw If the name of a nonexistent group is specified.
2954 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2956 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2958 synchronizeTinyInfoOnLeaves();
2959 std::vector<std::string> tmp(1);
2961 return getGroups(meshDimRelToMaxExt,tmp,renum);
2965 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2966 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2968 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2969 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2971 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2972 * according to the optional numbers of entities, if available.
2973 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2974 * delete this mesh using decrRef() as it is no more needed.
2975 * \throw If a name of a nonexistent group is present in \a grps.
2976 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2978 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2980 synchronizeTinyInfoOnLeaves();
2981 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2982 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2983 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2984 zeRet->setName(grps[0]);
2985 return zeRet.retn();
2989 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2990 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2992 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2993 * \param [in] fam - the name of the family whose mesh entities are included in the
2995 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2996 * according to the optional numbers of entities, if available.
2997 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2998 * delete this mesh using decrRef() as it is no more needed.
2999 * \throw If a name of a nonexistent family is present in \a grps.
3000 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3002 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3004 synchronizeTinyInfoOnLeaves();
3005 std::vector<std::string> tmp(1);
3007 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3011 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3012 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3014 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3015 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3017 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3018 * according to the optional numbers of entities, if available.
3019 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3020 * delete this mesh using decrRef() as it is no more needed.
3021 * \throw If a name of a nonexistent family is present in \a fams.
3022 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3024 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3026 synchronizeTinyInfoOnLeaves();
3027 if(meshDimRelToMaxExt==1)
3029 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3030 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3031 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3035 std::vector<int> famIds=getFamiliesIds(fams);
3036 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3037 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3039 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3041 zeRet=l1->getFamilyPart(0,0,renum);
3042 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3043 zeRet->setName(fams[0]);
3044 return zeRet.retn();
3048 * Returns ids of mesh entities contained in given families of a given dimension.
3049 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3051 * \param [in] fams - the names of the families of interest.
3052 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3053 * returned instead of ids.
3054 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3055 * numbers, if available and required, of mesh entities of the families. The caller
3056 * is to delete this array using decrRef() as it is no more needed.
3057 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3059 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3061 std::vector<int> famIds=getFamiliesIds(fams);
3062 if(meshDimRelToMaxExt==1)
3064 if((const DataArrayInt *)_fam_coords)
3066 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3068 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3070 da=_fam_coords->getIdsEqualList(0,0);
3072 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3077 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3079 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3081 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3083 return l1->getFamilyPartArr(0,0,renum);
3087 * Returns a MEDCouplingUMesh of a given relative dimension.
3088 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3089 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3090 * To build a valid MEDCouplingUMesh from the returned one in this case,
3091 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3092 * \param [in] meshDimRelToMax - the relative dimension of interest.
3093 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3094 * optional numbers of mesh entities.
3095 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3096 * delete using decrRef() as it is no more needed.
3097 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3098 * \sa getGenMeshAtLevel()
3100 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3102 synchronizeTinyInfoOnLeaves();
3103 if(meshDimRelToMaxExt==1)
3107 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3108 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3109 umesh->setCoords(cc);
3110 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3111 umesh->setName(getName());
3115 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3116 return l1->getWholeMesh(renum);
3120 * Returns a MEDCouplingUMesh of a given relative dimension.
3121 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3122 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3123 * To build a valid MEDCouplingUMesh from the returned one in this case,
3124 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3125 * \param [in] meshDimRelToMax - the relative dimension of interest.
3126 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3127 * optional numbers of mesh entities.
3128 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3129 * delete using decrRef() as it is no more needed.
3130 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3131 * \sa getMeshAtLevel()
3133 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3135 return getMeshAtLevel(meshDimRelToMax,renum);
3138 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3140 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3141 return l1->getDistributionOfTypes();
3145 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3146 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3147 * optional numbers of mesh entities.
3148 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3149 * delete using decrRef() as it is no more needed.
3150 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3152 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3154 return getMeshAtLevel(0,renum);
3158 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3159 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3160 * optional numbers of mesh entities.
3161 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3162 * delete using decrRef() as it is no more needed.
3163 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3165 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3167 return getMeshAtLevel(-1,renum);
3171 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3172 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3173 * optional numbers of mesh entities.
3174 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3175 * delete using decrRef() as it is no more needed.
3176 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3178 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3180 return getMeshAtLevel(-2,renum);
3184 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3185 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3186 * optional numbers of mesh entities.
3187 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3188 * delete using decrRef() as it is no more needed.
3189 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3191 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3193 return getMeshAtLevel(-3,renum);
3197 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3198 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3199 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3200 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3202 void MEDFileUMesh::forceComputationOfParts() const
3204 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3206 const MEDFileUMeshSplitL1 *elt(*it);
3208 elt->forceComputationOfParts();
3213 * This method returns a vector of mesh parts containing each exactly one geometric type.
3214 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3215 * This method is only for memory aware users.
3216 * The returned pointers are **NOT** new object pointer. No need to mange them.
3218 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3220 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3221 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3225 * This method returns the part of \a this having the geometric type \a gt.
3226 * If such part is not existing an exception will be thrown.
3227 * The returned pointer is **NOT** new object pointer. No need to mange it.
3229 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3231 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3232 int lev=(int)cm.getDimension()-getMeshDimension();
3233 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3234 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3238 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3239 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3241 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3243 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3244 return sp->getGeoTypes();
3248 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3249 * \param [in] gt - the geometric type for which the family field is asked.
3250 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3251 * delete using decrRef() as it is no more needed.
3252 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3254 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3256 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3257 int lev=(int)cm.getDimension()-getMeshDimension();
3258 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3259 return sp->extractFamilyFieldOnGeoType(gt);
3263 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3264 * \param [in] gt - the geometric type for which the number field is asked.
3265 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3266 * delete using decrRef() as it is no more needed.
3267 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3269 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3271 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3272 int lev=(int)cm.getDimension()-getMeshDimension();
3273 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3274 return sp->extractNumberFieldOnGeoType(gt);
3278 * This method returns for specified geometric type \a gt the relative level to \a this.
3279 * If the relative level is empty an exception will be thrown.
3281 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3283 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3284 int ret((int)cm.getDimension()-getMeshDimension());
3285 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3289 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3291 if(meshDimRelToMaxExt==1)
3292 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3293 if(meshDimRelToMaxExt>1)
3294 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3295 int tracucedRk=-meshDimRelToMaxExt;
3296 if(tracucedRk>=(int)_ms.size())
3297 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3298 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3299 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3300 return _ms[tracucedRk];
3303 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3305 if(meshDimRelToMaxExt==1)
3306 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3307 if(meshDimRelToMaxExt>1)
3308 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3309 int tracucedRk=-meshDimRelToMaxExt;
3310 if(tracucedRk>=(int)_ms.size())
3311 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3312 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3313 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3314 return _ms[tracucedRk];
3317 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3319 if(-meshDimRelToMax>=(int)_ms.size())
3320 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3322 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3324 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3326 int ref=(*it)->getMeshDimension();
3327 if(ref+i!=meshDim-meshDimRelToMax)
3328 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3334 * Sets the node coordinates array of \a this mesh.
3335 * \param [in] coords - the new node coordinates array.
3336 * \throw If \a coords == \c NULL.
3338 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3341 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3342 coords->checkAllocated();
3343 int nbOfTuples=coords->getNumberOfTuples();
3346 _fam_coords=DataArrayInt::New();
3347 _fam_coords->alloc(nbOfTuples,1);
3348 _fam_coords->fillWithZero();
3349 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3350 if((MEDFileUMeshSplitL1 *)(*it))
3351 (*it)->setCoords(coords);
3355 * Removes all groups of a given dimension in \a this mesh.
3356 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3357 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3359 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3361 if(meshDimRelToMaxExt==1)
3363 if((DataArrayInt *)_fam_coords)
3364 _fam_coords->fillWithZero();
3367 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3368 l1->eraseFamilyField();
3373 * Removes all families with ids not present in the family fields of \a this mesh.
3375 void MEDFileUMesh::optimizeFamilies()
3377 std::vector<int> levs=getNonEmptyLevelsExt();
3378 std::set<int> allFamsIds;
3379 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3381 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3382 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3384 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3387 std::set<std::string> famNamesToKill;
3388 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3390 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3391 famNamesToKill.insert((*it).first);
3393 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3394 _families.erase(*it);
3395 std::vector<std::string> grpNamesToKill;
3396 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3398 std::vector<std::string> tmp;
3399 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3401 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3402 tmp.push_back(*it2);
3407 tmp.push_back((*it).first);
3409 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3413 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3415 std::vector<int> levs=getNonEmptyLevels();
3416 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3417 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3418 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3419 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3420 int nbNodes=m0->getNumberOfNodes();
3421 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3422 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3423 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3424 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3425 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3426 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3427 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3428 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3429 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3430 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3431 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3432 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3433 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3434 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3435 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3436 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3437 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3438 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3439 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3440 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3441 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3442 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3443 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3444 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3445 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3446 m0->setCoords(tmp0->getCoords());
3447 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3448 m1->setCoords(m0->getCoords());
3449 _coords=m0->getCoords(); _coords->incrRef();
3450 // duplication of cells in group 'grpNameM1' on level -1
3451 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3452 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3453 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3454 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3455 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3457 newm1->setName(getName());
3458 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3460 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3461 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3462 newFam->alloc(newm1->getNumberOfCells(),1);
3463 int idd=getMaxFamilyId()+1;
3464 int globStart=0,start=0,end,globEnd;
3465 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3466 for(int i=0;i<nbOfChunks;i++)
3468 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3469 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3471 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3472 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3473 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3478 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3482 newm1->setCoords(getCoords());
3483 setMeshAtLevel(-1,newm1);
3484 setFamilyFieldArr(-1,newFam);
3485 std::string grpName2(grpNameM1); grpName2+="_dup";
3486 addFamily(grpName2,idd);
3487 addFamilyOnGrp(grpName2,grpName2);
3492 int newNbOfNodes=getCoords()->getNumberOfTuples();
3493 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3494 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3495 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3498 nodesDuplicated=nodeIdsToDuplicate.retn();
3499 cellsModified=cellsToModifyConn0.retn();
3500 cellsNotModified=cellsToModifyConn1.retn();
3504 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3505 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3506 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3508 * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering.
3509 * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered.
3511 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3513 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3514 std::vector<int> levs=getNonEmptyLevels();
3516 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3517 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3520 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3522 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3523 std::vector<int> code1=m->getDistributionOfTypes();
3524 end=PutInThirdComponentOfCodeOffset(code1,start);
3525 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3526 bool hasChanged=m->unPolyze();
3527 DataArrayInt *fake=0;
3528 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3529 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3531 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3534 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3535 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3537 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3538 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3539 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3540 setMeshAtLevel(*it,m);
3541 std::vector<int> code2=m->getDistributionOfTypes();
3542 end=PutInThirdComponentOfCodeOffset(code2,start);
3543 newCode.insert(newCode.end(),code2.begin(),code2.end());
3545 if(o2nCellsPart2->isIdentity())
3549 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3550 setFamilyFieldArr(*it,newFamField);
3554 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3555 setRenumFieldArr(*it,newNumField);
3560 newCode.insert(newCode.end(),code1.begin(),code1.end());
3566 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3567 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3568 o2nRenumCell=o2nRenumCellRet.retn();
3573 struct MEDLoaderAccVisit1
3575 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3576 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3577 int _new_nb_of_nodes;
3581 * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
3582 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3583 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3584 * -1 values in returned array means that the corresponding old node is no more used.
3586 * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
3587 * is modified in \a this.
3588 * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
3591 DataArrayInt *MEDFileUMesh::zipCoords()
3593 const DataArrayDouble *coo(getCoords());
3595 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3596 int nbOfNodes(coo->getNumberOfTuples());
3597 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3598 std::vector<int> neLevs(getNonEmptyLevels());
3599 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3601 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3602 if(zeLev->isMeshStoredSplitByType())
3604 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3605 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3607 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3611 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3612 mesh->computeNodeIdsAlg(nodeIdsInUse);
3615 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3616 if(nbrOfNodesInUse==nbOfNodes)
3617 return 0;//no need to update _part_coords
3618 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3619 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3620 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3621 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3622 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3623 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3624 if((const DataArrayInt *)_fam_coords)
3625 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3626 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3627 if((const DataArrayInt *)_num_coords)
3628 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3629 if((const DataArrayAsciiChar *)_name_coords)
3630 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3631 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3632 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3634 if((MEDFileUMeshSplitL1*)*it)
3636 (*it)->renumberNodesInConn(ret->begin());
3637 (*it)->setCoords(_coords);
3640 // updates _part_coords
3641 const PartDefinition *pc(_part_coords);
3644 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3645 _part_coords=tmpPD->composeWith(pc);
3651 * This method performs an extrusion along a path defined by \a m1D.
3652 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3653 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3654 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3655 * This method scans all levels in \a this
3656 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3658 * \param [in] m1D - the mesh defining the extrusion path.
3659 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3660 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3662 * \sa MEDCouplingUMesh::buildExtrudedMesh
3664 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3666 if(getMeshDimension()!=2)
3667 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3668 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3669 m1D->checkCoherency();
3670 if(m1D->getMeshDimension()!=1)
3671 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3672 int nbRep(m1D->getNumberOfCells());
3673 std::vector<int> levs(getNonEmptyLevels());
3674 std::vector<std::string> grps(getGroupsNames());
3675 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3676 DataArrayDouble *coords(0);
3677 std::size_t nbOfLevsOut(levs.size()+1);
3678 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3679 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3681 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3682 item=item->clone(false);
3683 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3684 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3685 tmp->changeSpaceDimension(3+(*lev),0.);
3686 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3687 zeList.push_back(elt);
3689 coords=elt->getCoords();
3692 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3693 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3695 (*it)->setName(getName());
3696 (*it)->setCoords(coords);
3698 for(std::size_t ii=0;ii!=zeList.size();ii++)
3701 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
3704 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
3705 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
3706 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
3707 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
3708 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
3709 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
3710 std::vector<const MEDCouplingUMesh *> elts(3);
3711 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
3712 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
3713 elt->setName(getName());
3716 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
3717 ret->setMeshAtLevel(lev,elt);
3719 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
3720 endLev=endLev->clone(false); endLev->setCoords(coords);
3721 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
3722 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
3723 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
3724 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
3725 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
3726 endLev->setName(getName());
3727 ret->setMeshAtLevel(levs.back()-1,endLev);
3729 for(std::size_t ii=0;ii!=zeList.size();ii++)
3732 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3733 std::vector< const DataArrayInt * > outGrps2;
3736 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3738 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
3739 if(!grpArr->empty())
3741 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
3742 int offset0(zeList[ii]->getNumberOfCells());
3743 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
3744 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
3745 std::ostringstream oss; oss << grpArr2->getName() << "_top";
3746 grpArr2->setName(oss.str());
3747 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3748 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3749 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3750 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3755 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3757 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
3758 if(!grpArr->empty())
3760 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
3761 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
3762 std::vector< const DataArrayInt *> grpArrs2(nbRep);
3763 for(int iii=0;iii<nbRep;iii++)
3765 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
3766 grpArrs2[iii]=grpArrs[iii];
3768 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
3769 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3770 std::ostringstream grpName; grpName << *grp << "_extruded";
3771 grpArrExt->setName(grpName.str());
3772 outGrps.push_back(grpArrExt);
3773 outGrps2.push_back(grpArrExt);
3776 ret->setGroupsAtLevel(lev,outGrps2);
3778 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3779 std::vector< const DataArrayInt * > outGrps2;
3780 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3782 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
3783 if(grpArr1->empty())
3785 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
3786 std::ostringstream grpName; grpName << *grp << "_top";
3787 grpArr2->setName(grpName.str());
3788 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
3789 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3790 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3792 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
3797 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
3798 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
3799 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
3801 * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple
3802 * corresponding quadratic cells. 1 is those creating the 'most' complex.
3803 * \param [in] eps - detection threshold for coordinates.
3804 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
3806 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
3808 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
3810 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3811 int initialNbNodes(getNumberOfNodes());
3812 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
3813 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
3815 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
3817 DataArrayDouble *zeCoords(m0->getCoords());
3818 ret->setMeshAtLevel(0,m0);
3819 std::vector<int> levs(getNonEmptyLevels());
3820 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
3823 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
3824 ret->setFamilyFieldArr(0,famFieldCpy);
3826 famField=getFamilyFieldAtLevel(1);
3829 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
3830 fam->fillWithZero();
3831 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
3832 ret->setFamilyFieldArr(1,fam);
3834 ret->copyFamGrpMapsFrom(*this);
3835 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
3836 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3840 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
3841 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
3843 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
3845 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
3847 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
3848 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
3851 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
3852 throw INTERP_KERNEL::Exception(oss.str().c_str());
3854 b->applyLin(1,initialNbNodes);
3855 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
3856 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
3857 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
3858 m1->renumberNodesInConn(renum->begin());
3859 m1->setCoords(zeCoords);
3860 ret->setMeshAtLevel(*lev,m1);
3861 famField=getFamilyFieldAtLevel(*lev);
3864 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
3865 ret->setFamilyFieldArr(*lev,famFieldCpy);
3872 * This method converts all quadratic cells in \a this into linear cells.
3873 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
3874 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
3876 * \param [in] eps - detection threshold for coordinates.
3877 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
3879 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
3881 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
3883 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3884 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
3885 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
3886 m0->convertQuadraticCellsToLinear();
3888 DataArrayDouble *zeCoords(m0->getCoords());
3889 ret->setMeshAtLevel(0,m0);
3890 std::vector<int> levs(getNonEmptyLevels());
3891 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
3894 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
3895 ret->setFamilyFieldArr(0,famFieldCpy);
3897 famField=getFamilyFieldAtLevel(1);
3900 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
3901 ret->setFamilyFieldArr(1,fam);
3903 ret->copyFamGrpMapsFrom(*this);
3904 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3908 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
3909 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
3910 m1->convertQuadraticCellsToLinear();
3913 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
3914 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
3917 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
3918 throw INTERP_KERNEL::Exception(oss.str().c_str());
3920 m1->renumberNodesInConn(b->begin());
3921 m1->setCoords(zeCoords);
3922 ret->setMeshAtLevel(*lev,m1);
3923 famField=getFamilyFieldAtLevel(*lev);
3926 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
3927 ret->setFamilyFieldArr(*lev,famFieldCpy);
3933 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
3935 clearNonDiscrAttributes();
3936 forceComputationOfParts();
3937 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
3938 std::vector<int> layer0;
3939 layer0.push_back(_order); //0 i
3940 layer0.push_back(_iteration);//1 i
3941 layer0.push_back(getSpaceDimension());//2 i
3942 tinyDouble.push_back(_time);//0 d
3943 tinyStr.push_back(_name);//0 s
3944 tinyStr.push_back(_desc_name);//1 s
3945 for(int i=0;i<getSpaceDimension();i++)
3946 tinyStr.push_back(_coords->getInfoOnComponent(i));
3947 layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
3948 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3950 tinyStr.push_back((*it).first);
3951 layer0.push_back((*it).second);
3953 layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
3954 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
3956 layer0.push_back((int)(*it0).second.size());
3957 tinyStr.push_back((*it0).first);
3958 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
3959 tinyStr.push_back(*it1);
3961 // sizeof(layer0)==3+aa+1+bb layer#0
3962 bigArrayD=_coords;// 0 bd
3963 bigArraysI.push_back(_fam_coords);// 0 bi
3964 bigArraysI.push_back(_num_coords);// 1 bi
3965 const PartDefinition *pd(_part_coords);
3967 layer0.push_back(-1);
3970 std::vector<int> tmp0;
3971 pd->serialize(tmp0,bigArraysI);
3972 tinyInt.push_back(tmp0.size());
3973 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
3976 std::vector<int> layer1;
3977 std::vector<int> levs(getNonEmptyLevels());
3978 layer1.push_back((int)levs.size());// 0 i <- key
3979 layer1.insert(layer1.end(),levs.begin(),levs.end());
3980 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3982 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
3983 lev->serialize(layer1,bigArraysI);
3985 // put layers all together.
3986 tinyInt.push_back(layer0.size());
3987 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
3988 tinyInt.push_back(layer1.size());
3989 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
3992 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
3993 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
3995 int sz0(tinyInt[0]);
3996 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
3997 int sz1(tinyInt[sz0+1]);
3998 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4000 std::reverse(layer0.begin(),layer0.end());
4001 std::reverse(layer1.begin(),layer1.end());
4002 std::reverse(tinyDouble.begin(),tinyDouble.end());
4003 std::reverse(tinyStr.begin(),tinyStr.end());
4004 std::reverse(bigArraysI.begin(),bigArraysI.end());
4006 _order=layer0.back(); layer0.pop_back();
4007 _iteration=layer0.back(); layer0.pop_back();
4008 int spaceDim(layer0.back()); layer0.pop_back();
4009 _time=tinyDouble.back(); tinyDouble.pop_back();
4010 _name=tinyStr.back(); tinyStr.pop_back();
4011 _desc_name=tinyStr.back(); tinyStr.pop_back();
4012 _coords=bigArrayD; _coords->rearrange(spaceDim);
4013 for(int i=0;i<spaceDim;i++)
4015 _coords->setInfoOnComponent(i,tinyStr.back());
4018 int nbOfFams(layer0.back()); layer0.pop_back();
4020 for(int i=0;i<nbOfFams;i++)
4022 _families[tinyStr.back()]=layer0.back();
4023 tinyStr.pop_back(); layer0.pop_back();
4025 int nbGroups(layer0.back()); layer0.pop_back();
4027 for(int i=0;i<nbGroups;i++)
4029 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4030 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4031 std::vector<std::string> fams(nbOfFamsOnGrp);
4032 for(int j=0;j<nbOfFamsOnGrp;j++)
4034 fams[j]=tinyStr.back(); tinyStr.pop_back();
4036 _groups[grpName]=fams;
4038 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4039 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4041 int isPd(layer0.back()); layer0.pop_back();
4044 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4045 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4046 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4049 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4051 int nbLevs(layer1.back()); layer1.pop_back();
4052 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4054 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4055 _ms.resize(maxLev+1);
4056 for(int i=0;i<nbLevs;i++)
4060 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4065 * Adds a group of nodes to \a this mesh.
4066 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4067 * The ids should be sorted and different each other (MED file norm).
4069 * \warning this method can alter default "FAMILLE_ZERO" family.
4070 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4072 * \throw If the node coordinates array is not set.
4073 * \throw If \a ids == \c NULL.
4074 * \throw If \a ids->getName() == "".
4075 * \throw If \a ids does not respect the MED file norm.
4076 * \throw If a group with name \a ids->getName() already exists.
4078 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4080 const DataArrayDouble *coords=_coords;
4082 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4083 int nbOfNodes=coords->getNumberOfTuples();
4084 if(!((DataArrayInt *)_fam_coords))
4085 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4087 addGroupUnderground(true,ids,_fam_coords);
4091 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4093 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4094 * The ids should be sorted and different each other (MED file norm).
4096 * \warning this method can alter default "FAMILLE_ZERO" family.
4097 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4099 * \throw If the node coordinates array is not set.
4100 * \throw If \a ids == \c NULL.
4101 * \throw If \a ids->getName() == "".
4102 * \throw If \a ids does not respect the MED file norm.
4103 * \throw If a group with name \a ids->getName() already exists.
4105 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4107 std::vector<int> levs=getNonEmptyLevelsExt();
4108 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4110 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4111 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4113 if(meshDimRelToMaxExt==1)
4114 { addNodeGroup(ids); return ; }
4115 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
4116 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
4117 addGroupUnderground(false,ids,fam);
4121 * \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).
4122 * \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)
4124 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
4127 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
4128 std::string grpName(ids->getName());
4130 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
4131 ids->checkStrictlyMonotonic(true);
4132 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
4133 std::vector<std::string> grpsNames=getGroupsNames();
4134 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
4136 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
4137 throw INTERP_KERNEL::Exception(oss.str().c_str());
4139 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
4140 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
4141 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
4142 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
4143 std::vector<int> familyIds;
4144 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
4145 int maxVal=getTheMaxAbsFamilyId()+1;
4146 std::map<std::string,int> families(_families);
4147 std::map<std::string, std::vector<std::string> > groups(_groups);
4148 std::vector<std::string> fams;
4149 bool created(false);
4150 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
4152 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
4153 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
4154 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
4155 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
4158 bool isFamPresent=false;
4159 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
4160 isFamPresent=(*itl)->presenceOfValue(*famId);
4162 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
4165 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
4166 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
4167 fams.push_back(locFamName);
4168 if(existsFamily(*famId))
4170 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
4171 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
4174 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
4178 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
4179 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
4180 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
4181 if(existsFamily(*famId))
4183 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
4184 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
4189 for(std::size_t i=0;i<familyIds.size();i++)
4191 DataArrayInt *da=idsPerfamiliyIds[i];
4192 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
4196 _groups[grpName]=fams;
4200 * Changes a name of a family specified by its id.
4201 * \param [in] id - the id of the family of interest.
4202 * \param [in] newFamName - the new family name.
4203 * \throw If no family with the given \a id exists.
4205 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4207 std::string oldName=getFamilyNameGivenId(id);
4208 _families.erase(oldName);
4209 _families[newFamName]=id;
4213 * Removes a mesh of a given dimension.
4214 * \param [in] meshDimRelToMax - the relative dimension of interest.
4215 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4217 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4219 std::vector<int> levSet=getNonEmptyLevels();
4220 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4221 if(it==levSet.end())
4222 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4223 int pos=(-meshDimRelToMax);
4228 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4229 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4230 * \param [in] m - the new mesh to set.
4231 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4233 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4234 * another node coordinates array.
4235 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4236 * to the existing meshes of other levels of \a this mesh.
4238 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4240 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4241 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4245 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4246 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4247 * \param [in] m - the new mesh to set.
4248 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4249 * writing \a this mesh in a MED file.
4250 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4252 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4253 * another node coordinates array.
4254 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4255 * to the existing meshes of other levels of \a this mesh.
4257 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4259 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4260 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4263 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4265 dealWithTinyInfo(m);
4266 std::vector<int> levSet=getNonEmptyLevels();
4267 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4269 if((DataArrayDouble *)_coords==0)
4271 DataArrayDouble *c=m->getCoords();
4276 if(m->getCoords()!=_coords)
4277 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4278 int sz=(-meshDimRelToMax)+1;
4279 if(sz>=(int)_ms.size())
4281 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4285 return _ms[-meshDimRelToMax];
4289 * This method allows to set at once the content of different levels in \a this.
4290 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4292 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4293 * \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.
4294 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4296 * \throw If \a there is a null pointer in \a ms.
4297 * \sa MEDFileUMesh::setMeshAtLevel
4299 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4303 const MEDCouplingUMesh *mRef=ms[0];
4305 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4306 std::string name(mRef->getName());
4307 const DataArrayDouble *coo(mRef->getCoords());
4310 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4312 const MEDCouplingUMesh *cur(*it);
4314 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4315 if(coo!=cur->getCoords())
4316 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4317 int mdim=cur->getMeshDimension();
4318 zeDim=std::max(zeDim,mdim);
4319 if(s.find(mdim)!=s.end())
4320 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4322 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4324 int mdim=(*it)->getMeshDimension();
4325 setName((*it)->getName());
4326 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4332 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4333 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4334 * The given meshes must share the same node coordinates array.
4335 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4336 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4337 * create in \a this mesh.
4338 * \throw If \a ms is empty.
4339 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4340 * to the existing meshes of other levels of \a this mesh.
4341 * \throw If the meshes in \a ms do not share the same node coordinates array.
4342 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4343 * of the given meshes.
4344 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4345 * \throw If names of some meshes in \a ms are equal.
4346 * \throw If \a ms includes a mesh with an empty name.
4348 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4351 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4352 int sz=(-meshDimRelToMax)+1;
4353 if(sz>=(int)_ms.size())
4355 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4356 DataArrayDouble *coo=checkMultiMesh(ms);
4357 if((DataArrayDouble *)_coords==0)
4363 if((DataArrayDouble *)_coords!=coo)
4364 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4365 std::vector<DataArrayInt *> corr;
4366 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4367 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4368 setMeshAtLevel(meshDimRelToMax,m,renum);
4369 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4370 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4374 * Creates groups at a given level in \a this mesh from a sequence of
4375 * meshes each representing a group.
4376 * The given meshes must share the same node coordinates array.
4377 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4378 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4379 * create in \a this mesh.
4380 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4382 * \throw If \a ms is empty.
4383 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4384 * to the existing meshes of other levels of \a this mesh.
4385 * \throw If the meshes in \a ms do not share the same node coordinates array.
4386 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4387 * of the given meshes.
4388 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4389 * \throw If names of some meshes in \a ms are equal.
4390 * \throw If \a ms includes a mesh with an empty name.
4392 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4395 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4396 int sz=(-meshDimRelToMax)+1;
4397 if(sz>=(int)_ms.size())
4399 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4400 DataArrayDouble *coo=checkMultiMesh(ms);
4401 if((DataArrayDouble *)_coords==0)
4407 if((DataArrayDouble *)_coords!=coo)
4408 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4409 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4410 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4412 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4414 DataArrayInt *arr=0;
4415 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4419 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4420 throw INTERP_KERNEL::Exception(oss.str().c_str());
4423 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4424 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4427 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4429 const DataArrayDouble *ret=ms[0]->getCoords();
4430 int mdim=ms[0]->getMeshDimension();
4431 for(unsigned int i=1;i<ms.size();i++)
4433 ms[i]->checkCoherency();
4434 if(ms[i]->getCoords()!=ret)
4435 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4436 if(ms[i]->getMeshDimension()!=mdim)
4437 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4439 return const_cast<DataArrayDouble *>(ret);
4443 * Sets the family field of a given relative dimension.
4444 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4445 * the family field is set.
4446 * \param [in] famArr - the array of the family field.
4447 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4448 * \throw If \a famArr has an invalid size.
4450 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4452 if(meshDimRelToMaxExt==1)
4459 DataArrayDouble *coo(_coords);
4461 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4462 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4467 if(meshDimRelToMaxExt>1)
4468 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4469 int traducedRk=-meshDimRelToMaxExt;
4470 if(traducedRk>=(int)_ms.size())
4471 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4472 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4473 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4474 return _ms[traducedRk]->setFamilyArr(famArr);
4478 * Sets the optional numbers of mesh entities of a given dimension.
4479 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4480 * \param [in] renumArr - the array of the numbers.
4481 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4482 * \throw If \a renumArr has an invalid size.
4484 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4486 if(meshDimRelToMaxExt==1)
4494 DataArrayDouble *coo(_coords);
4496 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4497 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4498 renumArr->incrRef();
4499 _num_coords=renumArr;
4503 if(meshDimRelToMaxExt>1)
4504 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4505 int traducedRk=-meshDimRelToMaxExt;
4506 if(traducedRk>=(int)_ms.size())
4507 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4508 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4509 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4510 return _ms[traducedRk]->setRenumArr(renumArr);
4514 * Sets the optional names of mesh entities of a given dimension.
4515 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4516 * \param [in] nameArr - the array of the names.
4517 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4518 * \throw If \a nameArr has an invalid size.
4520 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4522 if(meshDimRelToMaxExt==1)
4529 DataArrayDouble *coo(_coords);
4531 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4532 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4534 _name_coords=nameArr;
4537 if(meshDimRelToMaxExt>1)
4538 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4539 int traducedRk=-meshDimRelToMaxExt;
4540 if(traducedRk>=(int)_ms.size())
4541 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4542 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4543 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4544 return _ms[traducedRk]->setNameArr(nameArr);
4547 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4549 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4550 if((const MEDFileUMeshSplitL1 *)(*it))
4551 (*it)->synchronizeTinyInfo(*this);
4555 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4557 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4559 DataArrayInt *arr=_fam_coords;
4561 arr->changeValue(oldId,newId);
4562 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4564 MEDFileUMeshSplitL1 *sp=(*it);
4567 sp->changeFamilyIdArr(oldId,newId);
4572 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4574 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4575 const DataArrayInt *da(_fam_coords);
4577 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4578 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4580 const MEDFileUMeshSplitL1 *elt(*it);
4583 da=elt->getFamilyField();
4585 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4591 void MEDFileUMesh::computeRevNum() const
4593 if((const DataArrayInt *)_num_coords)
4596 int maxValue=_num_coords->getMaxValue(pos);
4597 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4601 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4603 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4606 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4608 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4609 ret.push_back((const DataArrayInt *)_fam_nodes);
4610 ret.push_back((const DataArrayInt *)_num_nodes);
4611 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4612 ret.push_back((const DataArrayInt *)_fam_cells);
4613 ret.push_back((const DataArrayInt *)_num_cells);
4614 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4615 ret.push_back((const DataArrayInt *)_fam_faces);
4616 ret.push_back((const DataArrayInt *)_num_faces);
4617 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4618 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4619 ret.push_back((const DataArrayInt *)_rev_num_cells);
4620 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4624 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4626 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4627 if((const DataArrayInt *)_fam_nodes)
4629 int val=_fam_nodes->getMaxValue(tmp);
4630 ret=std::max(ret,std::abs(val));
4632 if((const DataArrayInt *)_fam_cells)
4634 int val=_fam_cells->getMaxValue(tmp);
4635 ret=std::max(ret,std::abs(val));
4637 if((const DataArrayInt *)_fam_faces)
4639 int val=_fam_faces->getMaxValue(tmp);
4640 ret=std::max(ret,std::abs(val));
4645 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4647 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4648 if((const DataArrayInt *)_fam_nodes)
4650 int val=_fam_nodes->getMaxValue(tmp);
4651 ret=std::max(ret,val);
4653 if((const DataArrayInt *)_fam_cells)
4655 int val=_fam_cells->getMaxValue(tmp);
4656 ret=std::max(ret,val);
4658 if((const DataArrayInt *)_fam_faces)
4660 int val=_fam_faces->getMaxValue(tmp);
4661 ret=std::max(ret,val);
4666 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4668 int ret=std::numeric_limits<int>::max(),tmp=-1;
4669 if((const DataArrayInt *)_fam_nodes)
4671 int val=_fam_nodes->getMinValue(tmp);
4672 ret=std::min(ret,val);
4674 if((const DataArrayInt *)_fam_cells)
4676 int val=_fam_cells->getMinValue(tmp);
4677 ret=std::min(ret,val);
4679 if((const DataArrayInt *)_fam_faces)
4681 int val=_fam_faces->getMinValue(tmp);
4682 ret=std::min(ret,val);
4687 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4689 if(!MEDFileMesh::isEqual(other,eps,what))
4691 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4694 what="Mesh types differ ! This is structured and other is NOT !";
4697 const DataArrayInt *famc1=_fam_nodes;
4698 const DataArrayInt *famc2=otherC->_fam_nodes;
4699 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4701 what="Mismatch of families arr on nodes ! One is defined and not other !";
4706 bool ret=famc1->isEqual(*famc2);
4709 what="Families arr on nodes differ !";
4714 famc2=otherC->_fam_cells;
4715 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4717 what="Mismatch of families arr on cells ! One is defined and not other !";
4722 bool ret=famc1->isEqual(*famc2);
4725 what="Families arr on cells differ !";
4730 famc2=otherC->_fam_faces;
4731 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4733 what="Mismatch of families arr on faces ! One is defined and not other !";
4738 bool ret=famc1->isEqual(*famc2);
4741 what="Families arr on faces differ !";
4746 famc2=otherC->_num_nodes;
4747 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4749 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4754 bool ret=famc1->isEqual(*famc2);
4757 what="Numbering arr on nodes differ !";
4762 famc2=otherC->_num_cells;
4763 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4765 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4770 bool ret=famc1->isEqual(*famc2);
4773 what="Numbering arr on cells differ !";
4778 famc2=otherC->_num_faces;
4779 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4781 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4786 bool ret=famc1->isEqual(*famc2);
4789 what="Numbering arr on faces differ !";
4793 const DataArrayAsciiChar *d1=_names_cells;
4794 const DataArrayAsciiChar *d2=otherC->_names_cells;
4795 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4797 what="Mismatch of naming arr on cells ! One is defined and not other !";
4802 bool ret=d1->isEqual(*d2);
4805 what="Naming arr on cells differ !";
4810 d2=otherC->_names_faces;
4811 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4813 what="Mismatch of naming arr on faces ! One is defined and not other !";
4818 bool ret=d1->isEqual(*d2);
4821 what="Naming arr on faces differ !";
4826 d2=otherC->_names_nodes;
4827 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4829 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4834 bool ret=d1->isEqual(*d2);
4837 what="Naming arr on nodes differ !";
4844 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4846 MEDFileMesh::clearNonDiscrAttributes();
4847 const DataArrayInt *tmp=_fam_nodes;
4849 (const_cast<DataArrayInt *>(tmp))->setName("");
4852 (const_cast<DataArrayInt *>(tmp))->setName("");
4855 (const_cast<DataArrayInt *>(tmp))->setName("");
4858 (const_cast<DataArrayInt *>(tmp))->setName("");
4861 (const_cast<DataArrayInt *>(tmp))->setName("");
4864 (const_cast<DataArrayInt *>(tmp))->setName("");
4868 * Returns ids of mesh entities contained in given families of a given dimension.
4869 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4871 * \param [in] fams - the names of the families of interest.
4872 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4873 * returned instead of ids.
4874 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4875 * numbers, if available and required, of mesh entities of the families. The caller
4876 * is to delete this array using decrRef() as it is no more needed.
4877 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4879 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4881 std::vector<int> famIds(getFamiliesIds(fams));
4882 switch(meshDimRelToMaxExt)
4886 if((const DataArrayInt *)_fam_nodes)
4888 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4890 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4892 da=_fam_nodes->getIdsEqualList(0,0);
4894 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4899 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4904 if((const DataArrayInt *)_fam_cells)
4906 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4908 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4910 da=_fam_cells->getIdsEqualList(0,0);
4912 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4917 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4922 if((const DataArrayInt *)_fam_faces)
4924 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4926 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4928 da=_fam_faces->getIdsEqualList(0,0);
4930 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
4935 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
4939 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
4941 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
4945 * Sets the family field of a given relative dimension.
4946 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4947 * the family field is set.
4948 * \param [in] famArr - the array of the family field.
4949 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4950 * \throw If \a famArr has an invalid size.
4951 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
4953 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4955 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4957 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4958 switch(meshDimRelToMaxExt)
4962 int nbCells=mesh->getNumberOfCells();
4963 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4969 int nbNodes=mesh->getNumberOfNodes();
4970 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4976 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4977 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
4982 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
4989 * Sets the optional numbers of mesh entities of a given dimension.
4990 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4991 * \param [in] renumArr - the array of the numbers.
4992 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4993 * \throw If \a renumArr has an invalid size.
4994 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4996 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4998 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5000 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5001 switch(meshDimRelToMaxExt)
5005 int nbCells=mesh->getNumberOfCells();
5006 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5007 _num_cells=renumArr;
5012 int nbNodes=mesh->getNumberOfNodes();
5013 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5014 _num_nodes=renumArr;
5019 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5020 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5021 _num_faces=renumArr;
5025 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5028 renumArr->incrRef();
5032 * Sets the optional names of mesh entities of a given dimension.
5033 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5034 * \param [in] nameArr - the array of the names.
5035 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5036 * \throw If \a nameArr has an invalid size.
5038 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5040 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5042 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5043 switch(meshDimRelToMaxExt)
5047 int nbCells=mesh->getNumberOfCells();
5048 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5049 _names_cells=nameArr;
5054 int nbNodes=mesh->getNumberOfNodes();
5055 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5056 _names_nodes=nameArr;
5061 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5062 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5063 _names_cells=nameArr;
5066 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5073 * Returns the family field for mesh entities of a given dimension.
5074 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5075 * \return const DataArrayInt * - the family field. It is an array of ids of families
5076 * each mesh entity belongs to. It can be \c NULL.
5077 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5079 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5081 switch(meshDimRelToMaxExt)
5090 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5095 * Returns the optional numbers of mesh entities of a given dimension.
5096 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5097 * \return const DataArrayInt * - the array of the entity numbers.
5098 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5099 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5101 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5103 switch(meshDimRelToMaxExt)
5112 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5117 * Returns the optional numbers of mesh entities of a given dimension transformed using
5118 * DataArrayInt::invertArrayN2O2O2N().
5119 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5120 * \return const DataArrayInt * - the array of the entity numbers transformed using
5121 * DataArrayInt::invertArrayN2O2O2N().
5122 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5123 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5125 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5127 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5128 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5129 if(meshDimRelToMaxExt==0)
5131 if((const DataArrayInt *)_num_cells)
5134 int maxValue=_num_cells->getMaxValue(pos);
5135 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5136 return _rev_num_cells;
5139 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5143 if((const DataArrayInt *)_num_nodes)
5146 int maxValue=_num_nodes->getMaxValue(pos);
5147 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5148 return _rev_num_nodes;
5151 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5155 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5157 switch(meshDimRelToMaxExt)
5160 return _names_cells;
5162 return _names_nodes;
5164 return _names_faces;
5166 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5171 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5172 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5174 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5176 std::vector<int> ret(1);
5181 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5182 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5184 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5186 std::vector<int> ret(2);
5192 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5194 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5196 std::vector<int> ret;
5197 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5208 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5210 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5212 std::vector<int> ret;
5213 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5224 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5226 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5228 std::vector<int> ret;
5229 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5240 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5242 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5244 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5248 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5250 DataArrayInt *arr=_fam_nodes;
5252 arr->changeValue(oldId,newId);
5255 arr->changeValue(oldId,newId);
5258 arr->changeValue(oldId,newId);
5261 void MEDFileStructuredMesh::deepCpyAttributes()
5263 if((const DataArrayInt*)_fam_nodes)
5264 _fam_nodes=_fam_nodes->deepCpy();
5265 if((const DataArrayInt*)_num_nodes)
5266 _num_nodes=_num_nodes->deepCpy();
5267 if((const DataArrayAsciiChar*)_names_nodes)
5268 _names_nodes=_names_nodes->deepCpy();
5269 if((const DataArrayInt*)_fam_cells)
5270 _fam_cells=_fam_cells->deepCpy();
5271 if((const DataArrayInt*)_num_cells)
5272 _num_cells=_num_cells->deepCpy();
5273 if((const DataArrayAsciiChar*)_names_cells)
5274 _names_cells=_names_cells->deepCpy();
5275 if((const DataArrayInt*)_fam_faces)
5276 _fam_faces=_fam_faces->deepCpy();
5277 if((const DataArrayInt*)_num_faces)
5278 _num_faces=_num_faces->deepCpy();
5279 if((const DataArrayAsciiChar*)_names_faces)
5280 _names_faces=_names_faces->deepCpy();
5281 if((const DataArrayInt*)_rev_num_nodes)
5282 _rev_num_nodes=_rev_num_nodes->deepCpy();
5283 if((const DataArrayInt*)_rev_num_cells)
5284 _rev_num_cells=_rev_num_cells->deepCpy();
5288 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5290 * \return a pointer to cartesian mesh that need to be managed by the caller.
5291 * \warning the returned pointer has to be managed by the caller.
5295 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5296 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5297 * \param [in] renum - it must be \c false.
5298 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5299 * delete using decrRef() as it is no more needed.
5301 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
5304 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5305 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5306 switch(meshDimRelToMax)
5312 return const_cast<MEDCouplingStructuredMesh *>(m);
5317 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5318 buildMinusOneImplicitPartIfNeeded();
5319 MEDCouplingMesh *ret(_faces_if_necessary);
5325 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5330 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5331 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5332 * \return int - the number of entities.
5333 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5335 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5337 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5339 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5340 switch(meshDimRelToMaxExt)
5343 return cmesh->getNumberOfCells();
5345 return cmesh->getNumberOfNodes();
5347 return cmesh->getNumberOfCellsOfSubLevelMesh();
5349 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5353 int MEDFileStructuredMesh::getNumberOfNodes() const
5355 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5357 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5358 return cmesh->getNumberOfNodes();
5361 bool MEDFileStructuredMesh::hasImplicitPart() const
5367 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5369 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5371 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5372 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5375 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5376 if(cm.getReverseExtrudedType()!=gt)
5377 throw INTERP_KERNEL::Exception(MSG);
5378 buildImplicitPart();
5379 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5383 if(gt!=zeFaceMesh->getCellModelEnum())
5384 throw INTERP_KERNEL::Exception(MSG);
5385 return zeFaceMesh->getNumberOfCells();
5389 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5391 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5393 buildImplicitPart();
5396 void MEDFileStructuredMesh::buildImplicitPart() const
5398 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5400 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5401 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5404 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5406 _faces_if_necessary=0;
5410 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5411 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5413 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5415 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5417 return _faces_if_necessary;
5420 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5422 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5424 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5425 switch(meshDimRelToMax)
5429 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5434 int mdim(cmesh->getMeshDimension());
5436 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5437 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5441 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5445 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5447 if(st.getNumberOfItems()!=1)
5448 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 !");
5449 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5450 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5451 if(getNumberOfNodes()!=(int)nodesFetched.size())
5452 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5453 if(st[0].getPflName().empty())
5455 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5458 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5459 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5460 int sz(nodesFetched.size());
5461 for(const int *work=arr->begin();work!=arr->end();work++)
5463 std::vector<int> conn;
5464 cmesh->getNodeIdsOfCell(*work,conn);
5465 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5466 if(*it>=0 && *it<sz)
5467 nodesFetched[*it]=true;
5469 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5473 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5475 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5479 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5480 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5482 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5483 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5485 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5488 if(!mrs || mrs->isCellFamilyFieldReading())
5490 famCells=DataArrayInt::New();
5491 famCells->alloc(nbOfElt,1);
5492 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
5495 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5498 if(!mrs || mrs->isCellNumFieldReading())
5500 numCells=DataArrayInt::New();
5501 numCells->alloc(nbOfElt,1);
5502 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
5505 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5508 if(!mrs || mrs->isCellNameFieldReading())
5510 namesCells=DataArrayAsciiChar::New();
5511 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5512 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
5513 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5518 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5520 setName(strm->getName());
5521 setDescription(strm->getDescription());
5522 setUnivName(strm->getUnivName());
5523 setIteration(strm->getIteration());
5524 setOrder(strm->getOrder());
5525 setTimeValue(strm->getTime());
5526 setTimeUnit(strm->getTimeUnit());
5527 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5528 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5529 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5532 if(!mrs || mrs->isNodeFamilyFieldReading())
5534 int nbNodes(getNumberOfNodes());
5536 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5537 _fam_nodes=DataArrayInt::New();
5538 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5539 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...
5540 _fam_nodes->fillWithZero();
5541 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
5544 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5547 if(!mrs || mrs->isNodeNumFieldReading())
5549 _num_nodes=DataArrayInt::New();
5550 _num_nodes->alloc(nbOfElt,1);
5551 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
5554 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5557 if(!mrs || mrs->isNodeNameFieldReading())
5559 _names_nodes=DataArrayAsciiChar::New();
5560 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5561 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
5562 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5565 int meshDim(getStructuredMesh()->getMeshDimension());
5566 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5568 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5571 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5573 int meshDim(getStructuredMesh()->getMeshDimension());
5574 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5576 if((const DataArrayInt *)_fam_cells)
5577 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
5578 if((const DataArrayInt *)_fam_faces)
5579 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
5580 if((const DataArrayInt *)_fam_nodes)
5581 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
5582 if((const DataArrayInt *)_num_cells)
5583 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
5584 if((const DataArrayInt *)_num_faces)
5585 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
5586 if((const DataArrayInt *)_num_nodes)
5587 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
5588 if((const DataArrayAsciiChar *)_names_cells)
5590 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5592 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5593 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5594 throw INTERP_KERNEL::Exception(oss.str().c_str());
5596 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
5598 if((const DataArrayAsciiChar *)_names_faces)
5600 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5602 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5603 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5604 throw INTERP_KERNEL::Exception(oss.str().c_str());
5606 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
5608 if((const DataArrayAsciiChar *)_names_nodes)
5610 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5612 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5613 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5614 throw INTERP_KERNEL::Exception(oss.str().c_str());
5616 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
5619 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5623 * Returns an empty instance of MEDFileCMesh.
5624 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5625 * mesh using decrRef() as it is no more needed.
5627 MEDFileCMesh *MEDFileCMesh::New()
5629 return new MEDFileCMesh;
5633 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5634 * file. The first mesh in the file is loaded.
5635 * \param [in] fileName - the name of MED file to read.
5636 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5637 * mesh using decrRef() as it is no more needed.
5638 * \throw If the file is not readable.
5639 * \throw If there is no meshes in the file.
5640 * \throw If the mesh in the file is not a Cartesian one.
5642 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5644 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5647 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5648 throw INTERP_KERNEL::Exception(oss.str().c_str());
5650 MEDFileUtilities::CheckFileForRead(fileName);
5651 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5653 ParaMEDMEM::MEDCouplingMeshType meshType;
5655 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5656 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5660 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5661 * file. The mesh to load is specified by its name and numbers of a time step and an
5663 * \param [in] fileName - the name of MED file to read.
5664 * \param [in] mName - the name of the mesh to read.
5665 * \param [in] dt - the number of a time step.
5666 * \param [in] it - the number of an iteration.
5667 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5668 * mesh using decrRef() as it is no more needed.
5669 * \throw If the file is not readable.
5670 * \throw If there is no mesh with given attributes in the file.
5671 * \throw If the mesh in the file is not a Cartesian one.
5673 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5675 MEDFileUtilities::CheckFileForRead(fileName);
5676 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5677 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5680 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5682 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5685 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5687 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5688 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5693 * Returns the dimension on cells in \a this mesh.
5694 * \return int - the mesh dimension.
5695 * \throw If there are no cells in this mesh.
5697 int MEDFileCMesh::getMeshDimension() const
5699 if(!((const MEDCouplingCMesh*)_cmesh))
5700 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5701 return _cmesh->getMeshDimension();
5705 * Returns the dimension on nodes in \a this mesh.
5706 * \return int - the space dimension.
5707 * \throw If there are no cells in this mesh.
5709 int MEDFileCMesh::getSpaceDimension() const
5711 if(!((const MEDCouplingCMesh*)_cmesh))
5712 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5713 return _cmesh->getSpaceDimension();
5717 * Returns a string describing \a this mesh.
5718 * \return std::string - the mesh information string.
5720 std::string MEDFileCMesh::simpleRepr() const
5722 return MEDFileStructuredMesh::simpleRepr();
5726 * Returns a full textual description of \a this mesh.
5727 * \return std::string - the string holding the mesh description.
5729 std::string MEDFileCMesh::advancedRepr() const
5731 return simpleRepr();
5734 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5736 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5740 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5742 return new MEDFileCMesh;
5745 MEDFileMesh *MEDFileCMesh::deepCpy() const
5747 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5748 if((const MEDCouplingCMesh*)_cmesh)
5749 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5750 ret->deepCpyAttributes();
5755 * Checks if \a this and another mesh are equal.
5756 * \param [in] other - the mesh to compare with.
5757 * \param [in] eps - a precision used to compare real values.
5758 * \param [in,out] what - the string returning description of unequal data.
5759 * \return bool - \c true if the meshes are equal, \c false, else.
5761 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5763 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5765 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5768 what="Mesh types differ ! This is cartesian and other is NOT !";
5771 clearNonDiscrAttributes();
5772 otherC->clearNonDiscrAttributes();
5773 const MEDCouplingCMesh *coo1=_cmesh;
5774 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5775 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5777 what="Mismatch of cartesian meshes ! One is defined and not other !";
5782 bool ret=coo1->isEqual(coo2,eps);
5785 what="cartesian meshes differ !";
5793 * Clears redundant attributes of incorporated data arrays.
5795 void MEDFileCMesh::clearNonDiscrAttributes() const
5797 MEDFileStructuredMesh::clearNonDiscrAttributes();
5798 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
5801 MEDFileCMesh::MEDFileCMesh()
5805 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5808 loadCMeshFromFile(fid,mName,dt,it,mrs);
5810 catch(INTERP_KERNEL::Exception& e)
5815 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5817 ParaMEDMEM::MEDCouplingMeshType meshType;
5820 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5821 if(meshType!=CARTESIAN)
5823 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
5824 throw INTERP_KERNEL::Exception(oss.str().c_str());
5826 MEDFileCMeshL2 loaderl2;
5827 loaderl2.loadAll(fid,mid,mName,dt,it);
5828 MEDCouplingCMesh *mesh=loaderl2.getMesh();
5831 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5835 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
5836 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
5838 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
5840 synchronizeTinyInfoOnLeaves();
5844 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
5846 synchronizeTinyInfoOnLeaves();
5851 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
5852 * \param [in] m - the new MEDCouplingCMesh to refer to.
5853 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5856 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
5858 dealWithTinyInfo(m);
5864 void MEDFileCMesh::writeLL(med_idt fid) const
5866 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5867 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5868 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5869 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5870 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5871 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5872 int spaceDim(_cmesh->getSpaceDimension());
5873 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5874 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5875 for(int i=0;i<spaceDim;i++)
5877 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
5879 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5880 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
5881 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
5883 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5884 MEDmeshUniversalNameWr(fid,maa);
5885 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
5886 for(int i=0;i<spaceDim;i++)
5888 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
5889 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
5892 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5893 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5896 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
5898 const MEDCouplingCMesh *cmesh=_cmesh;
5901 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
5902 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
5903 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
5904 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
5907 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
5909 return new MEDFileCurveLinearMesh;
5912 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5914 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5917 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5918 throw INTERP_KERNEL::Exception(oss.str().c_str());
5920 MEDFileUtilities::CheckFileForRead(fileName);
5921 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5923 ParaMEDMEM::MEDCouplingMeshType meshType;
5925 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5926 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
5929 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5931 MEDFileUtilities::CheckFileForRead(fileName);
5932 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5933 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
5936 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
5938 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5941 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
5943 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5944 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5948 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5950 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5954 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5956 return new MEDFileCurveLinearMesh;
5959 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5961 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5962 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5963 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5964 ret->deepCpyAttributes();
5968 int MEDFileCurveLinearMesh::getMeshDimension() const
5970 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5971 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5972 return _clmesh->getMeshDimension();
5975 std::string MEDFileCurveLinearMesh::simpleRepr() const
5977 return MEDFileStructuredMesh::simpleRepr();
5980 std::string MEDFileCurveLinearMesh::advancedRepr() const
5982 return simpleRepr();
5985 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5987 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5989 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5992 what="Mesh types differ ! This is curve linear and other is NOT !";
5995 clearNonDiscrAttributes();
5996 otherC->clearNonDiscrAttributes();
5997 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5998 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5999 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6001 what="Mismatch of curve linear meshes ! One is defined and not other !";
6006 bool ret=coo1->isEqual(coo2,eps);
6009 what="curve linear meshes differ !";
6016 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6018 MEDFileStructuredMesh::clearNonDiscrAttributes();
6019 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6022 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6024 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6027 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6028 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6029 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6030 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6033 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6035 synchronizeTinyInfoOnLeaves();
6039 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6041 dealWithTinyInfo(m);
6047 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6049 synchronizeTinyInfoOnLeaves();
6053 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6057 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6060 loadCLMeshFromFile(fid,mName,dt,it,mrs);
6062 catch(INTERP_KERNEL::Exception& e)
6067 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6069 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6070 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6071 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6072 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6073 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6074 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6075 int spaceDim=_clmesh->getSpaceDimension();
6076 int meshDim=_clmesh->getMeshDimension();
6077 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6078 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6079 const DataArrayDouble *coords=_clmesh->getCoords();
6081 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6082 for(int i=0;i<spaceDim;i++)
6084 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6086 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6087 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
6088 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
6090 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
6091 MEDmeshUniversalNameWr(fid,maa);
6092 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
6093 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6094 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
6096 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
6098 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6099 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6102 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6104 ParaMEDMEM::MEDCouplingMeshType meshType;
6107 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6108 if(meshType!=CURVE_LINEAR)
6110 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6111 throw INTERP_KERNEL::Exception(oss.str().c_str());
6113 MEDFileCLMeshL2 loaderl2;
6114 loaderl2.loadAll(fid,mid,mName,dt,it);
6115 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6118 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6121 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6123 return new MEDFileMeshMultiTS;
6126 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6128 return new MEDFileMeshMultiTS(fileName);
6131 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6133 return new MEDFileMeshMultiTS(fileName,mName);
6136 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6138 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6139 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6141 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6142 if((const MEDFileMesh *)*it)
6143 meshOneTs[i]=(*it)->deepCpy();
6144 ret->_mesh_one_ts=meshOneTs;
6148 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6150 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6153 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6155 std::vector<const BigMemoryObject *> ret;
6156 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6157 ret.push_back((const MEDFileMesh *)*it);
6161 std::string MEDFileMeshMultiTS::getName() const
6163 if(_mesh_one_ts.empty())
6164 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6165 return _mesh_one_ts[0]->getName();
6168 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6170 std::string oldName(getName());
6171 std::vector< std::pair<std::string,std::string> > v(1);
6172 v[0].first=oldName; v[0].second=newMeshName;
6176 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6179 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6181 MEDFileMesh *cur(*it);
6183 ret=cur->changeNames(modifTab) || ret;
6188 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6190 if(_mesh_one_ts.empty())
6191 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6192 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6195 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6198 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6199 _mesh_one_ts.resize(1);
6200 mesh1TimeStep->incrRef();
6201 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6202 _mesh_one_ts[0]=mesh1TimeStep;
6205 void MEDFileMeshMultiTS::write(med_idt fid) const
6207 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6209 (*it)->copyOptionsFrom(*this);
6214 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6216 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6217 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6218 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6219 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6223 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6224 {//for the moment to be improved
6225 _mesh_one_ts.resize(1);
6226 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
6229 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6233 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6236 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6239 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6240 throw INTERP_KERNEL::Exception(oss.str().c_str());
6242 MEDFileUtilities::CheckFileForRead(fileName);
6243 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6245 ParaMEDMEM::MEDCouplingMeshType meshType;
6247 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6248 loadFromFile(fileName,ms.front());
6250 catch(INTERP_KERNEL::Exception& e)
6255 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6258 loadFromFile(fileName,mName);
6260 catch(INTERP_KERNEL::Exception& e)
6265 MEDFileMeshes *MEDFileMeshes::New()
6267 return new MEDFileMeshes;
6270 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6272 return new MEDFileMeshes(fileName);
6275 void MEDFileMeshes::write(med_idt fid) const
6278 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6280 (*it)->copyOptionsFrom(*this);
6285 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6287 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6288 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6289 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6290 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6295 int MEDFileMeshes::getNumberOfMeshes() const
6297 return _meshes.size();
6300 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6302 return new MEDFileMeshesIterator(this);
6305 /** Return a borrowed reference (caller is not responsible) */
6306 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6308 if(i<0 || i>=(int)_meshes.size())
6310 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6311 throw INTERP_KERNEL::Exception(oss.str().c_str());
6313 return _meshes[i]->getOneTimeStep();
6316 /** Return a borrowed reference (caller is not responsible) */
6317 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6319 std::vector<std::string> ms=getMeshesNames();
6320 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6323 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6324 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6325 throw INTERP_KERNEL::Exception(oss.str().c_str());
6327 return getMeshAtPos((int)std::distance(ms.begin(),it));
6330 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6332 std::vector<std::string> ret(_meshes.size());
6334 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6336 const MEDFileMeshMultiTS *f=(*it);
6339 ret[i]=f->getName();
6343 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6344 throw INTERP_KERNEL::Exception(oss.str().c_str());
6350 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6353 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6355 MEDFileMeshMultiTS *cur(*it);
6357 ret=cur->changeNames(modifTab) || ret;
6362 void MEDFileMeshes::resize(int newSize)
6364 _meshes.resize(newSize);
6367 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6370 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6371 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6372 elt->setOneTimeStep(mesh);
6373 _meshes.push_back(elt);
6376 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6379 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6380 if(i>=(int)_meshes.size())
6381 _meshes.resize(i+1);
6382 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6383 elt->setOneTimeStep(mesh);
6387 void MEDFileMeshes::destroyMeshAtPos(int i)
6389 if(i<0 || i>=(int)_meshes.size())
6391 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6392 throw INTERP_KERNEL::Exception(oss.str().c_str());
6394 _meshes.erase(_meshes.begin()+i);
6397 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6399 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6401 _meshes.resize(ms.size());
6402 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6403 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6406 MEDFileMeshes::MEDFileMeshes()
6410 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6413 loadFromFile(fileName);
6415 catch(INTERP_KERNEL::Exception& /*e*/)
6419 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6421 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6423 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6424 if((const MEDFileMeshMultiTS *)*it)
6425 meshes[i]=(*it)->deepCpy();
6426 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6427 ret->_meshes=meshes;
6431 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6433 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6436 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6438 std::vector<const BigMemoryObject *> ret;
6439 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6440 ret.push_back((const MEDFileMeshMultiTS *)*it);
6444 std::string MEDFileMeshes::simpleRepr() const
6446 std::ostringstream oss;
6447 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6448 simpleReprWithoutHeader(oss);
6452 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6454 int nbOfMeshes=getNumberOfMeshes();
6455 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6456 std::vector<std::string> mns=getMeshesNames();
6457 for(int i=0;i<nbOfMeshes;i++)
6458 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6461 void MEDFileMeshes::checkCoherency() const
6463 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6465 std::set<std::string> s;
6466 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6468 const MEDFileMeshMultiTS *elt=(*it);
6471 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6472 throw INTERP_KERNEL::Exception(oss.str().c_str());
6474 std::size_t sz=s.size();
6475 s.insert(std::string((*it)->getName()));
6478 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6479 throw INTERP_KERNEL::Exception(oss.str().c_str());
6484 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6489 _nb_iter=ms->getNumberOfMeshes();
6493 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6497 MEDFileMesh *MEDFileMeshesIterator::nextt()
6499 if(_iter_id<_nb_iter)
6501 MEDFileMeshes *ms(_ms);
6503 return ms->getMeshAtPos(_iter_id++);