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 "MEDFileSafeCaller.txx"
27 #include "MEDLoaderBase.hxx"
29 #include "MEDCouplingUMesh.hxx"
31 #include "InterpKernelAutoPtr.hxx"
36 extern med_geometry_type typmai3[34];
38 using namespace ParaMEDMEM;
40 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
42 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
46 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
48 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
49 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
51 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
52 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
53 ret+=(*it2).capacity();
55 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
56 ret+=(*it).first.capacity()+sizeof(int);
60 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
62 std::vector<const BigMemoryObject *> ret(1);
63 ret[0]=(const MEDFileEquivalences *)_equiv;
68 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
69 * file. The first mesh in the file is loaded.
70 * \param [in] fileName - the name of MED file to read.
71 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
72 * mesh using decrRef() as it is no more needed.
73 * \throw If the file is not readable.
74 * \throw If there is no meshes in the file.
75 * \throw If the mesh in the file is of a not supported type.
77 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
79 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
82 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
83 throw INTERP_KERNEL::Exception(oss.str().c_str());
85 MEDFileUtilities::CheckFileForRead(fileName);
86 ParaMEDMEM::MEDCouplingMeshType meshType;
87 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
90 ParaMEDMEM::MEDCouplingAxisType dummy3;
91 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
92 MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ret;
97 ret=MEDFileUMesh::New();
102 ret=MEDFileCMesh::New();
107 ret=MEDFileCurveLinearMesh::New();
112 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
113 throw INTERP_KERNEL::Exception(oss.str().c_str());
116 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
121 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
122 * file. The mesh to load is specified by its name and numbers of a time step and an
124 * \param [in] fileName - the name of MED file to read.
125 * \param [in] mName - the name of the mesh to read.
126 * \param [in] dt - the number of a time step.
127 * \param [in] it - the number of an iteration.
128 * \param [in] joints - the sub-domain joints to use instead of those that can be read
129 * from the MED file. Usually this joints are those just read by another iteration
130 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
131 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
132 * mesh using decrRef() as it is no more needed.
133 * \throw If the file is not readable.
134 * \throw If there is no mesh with given attributes in the file.
135 * \throw If the mesh in the file is of a not supported type.
137 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
139 MEDFileUtilities::CheckFileForRead(fileName);
140 ParaMEDMEM::MEDCouplingMeshType meshType;
141 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
144 ParaMEDMEM::MEDCouplingAxisType dummy3;
145 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
146 MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ret;
151 ret=MEDFileUMesh::New();
156 ret=MEDFileCMesh::New();
161 ret=MEDFileCurveLinearMesh::New();
166 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
167 throw INTERP_KERNEL::Exception(oss.str().c_str());
170 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
175 * Writes \a this mesh into an open MED file specified by its descriptor.
176 * \param [in] fid - the MED file descriptor.
177 * \throw If the mesh name is not set.
178 * \throw If the file is open for reading only.
179 * \throw If the writing mode == 1 and the same data is present in an existing file.
181 void MEDFileMesh::write(med_idt fid) const
184 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
186 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
189 const MEDFileEquivalences *eqs(_equiv);
195 * Writes \a this mesh into a MED file specified by its name.
196 * \param [in] fileName - the MED file name.
197 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
198 * - 2 - erase; an existing file is removed.
199 * - 1 - append; same data should not be present in an existing file.
200 * - 0 - overwrite; same data present in an existing file is overwritten.
201 * \throw If the mesh name is not set.
202 * \throw If \a mode == 1 and the same data is present in an existing file.
204 void MEDFileMesh::write(const std::string& fileName, int mode) const
206 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
207 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
208 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
209 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
214 * Checks if \a this and another mesh are equal.
215 * \param [in] other - the mesh to compare with.
216 * \param [in] eps - a precision used to compare real values.
217 * \param [in,out] what - the string returning description of unequal data.
218 * \return bool - \c true if the meshes are equal, \c false, else.
220 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
222 if(_order!=other->_order)
224 what="Orders differ !";
227 if(_iteration!=other->_iteration)
229 what="Iterations differ !";
232 if(fabs(_time-other->_time)>eps)
234 what="Time values differ !";
237 if(_dt_unit!=other->_dt_unit)
239 what="Time units differ !";
242 if(_name!=other->_name)
244 what="Names differ !";
247 //univ_name has been ignored -> not a bug because it is a mutable attribute
248 if(_desc_name!=other->_desc_name)
250 what="Description names differ !";
253 if(!areGrpsEqual(other,what))
255 if(!areFamsEqual(other,what))
257 if(!areEquivalencesEqual(other,what))
262 void MEDFileMesh::setName(const std::string& name)
268 * Clears redundant attributes of incorporated data arrays.
270 void MEDFileMesh::clearNonDiscrAttributes() const
275 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
277 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
279 if((*it).first==_name)
289 * Copies data on groups and families from another mesh.
290 * \param [in] other - the mesh to copy the data from.
292 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
294 _groups=other._groups;
295 _families=other._families;
300 * This method clear all the groups in the map.
301 * So this method does not operate at all on arrays.
302 * So this method can lead to orphan families.
304 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
306 void MEDFileMesh::clearGrpMap()
312 * This method clear all the families in the map.
313 * So this method does not operate at all on arrays.
314 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
316 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
318 void MEDFileMesh::clearFamMap()
324 * This method clear all the families and groups in the map.
325 * So this method does not operate at all on arrays.
326 * As all groups and families entry will be removed after
327 * 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.
329 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
331 void MEDFileMesh::clearFamGrpMaps()
338 * Returns names of families constituting a group.
339 * \param [in] name - the name of the group of interest.
340 * \return std::vector<std::string> - a sequence of names of the families.
341 * \throw If the name of a nonexistent group is specified.
343 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
345 std::string oname(name);
346 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
347 if(it==_groups.end())
349 std::vector<std::string> grps=getGroupsNames();
350 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
351 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
352 throw INTERP_KERNEL::Exception(oss.str().c_str());
358 * Returns names of families constituting some groups.
359 * \param [in] grps - a sequence of names of groups of interest.
360 * \return std::vector<std::string> - a sequence of names of the families.
361 * \throw If a name of a nonexistent group is present in \a grps.
363 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
365 std::set<std::string> fams;
366 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
368 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
369 if(it2==_groups.end())
371 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
372 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
373 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
374 throw INTERP_KERNEL::Exception(oss.str().c_str());
376 fams.insert((*it2).second.begin(),(*it2).second.end());
378 std::vector<std::string> fams2(fams.begin(),fams.end());
383 * Returns ids of families constituting a group.
384 * \param [in] name - the name of the group of interest.
385 * \return std::vector<int> - sequence of ids of the families.
386 * \throw If the name of a nonexistent group is specified.
388 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
390 std::string oname(name);
391 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
392 std::vector<std::string> grps=getGroupsNames();
393 if(it==_groups.end())
395 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
396 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
397 throw INTERP_KERNEL::Exception(oss.str().c_str());
399 return getFamiliesIds((*it).second);
403 * Sets names of families constituting a group. If data on families of this group is
404 * already present, it is overwritten. Every family in \a fams is checked, and if a
405 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
406 * \param [in] name - the name of the group of interest.
407 * \param [in] fams - a sequence of names of families constituting the group.
409 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
411 std::string oname(name);
413 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
415 std::map<std::string,int>::iterator it2=_families.find(*it1);
416 if(it2==_families.end())
422 * Sets families constituting a group. The families are specified by their ids.
423 * If a family name is not found by its id, an exception is thrown.
424 * If several families have same id, the first one in lexical order is taken.
425 * \param [in] name - the name of the group of interest.
426 * \param [in] famIds - a sequence of ids of families constituting the group.
427 * \throw If a family name is not found by its id.
429 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
431 std::string oname(name);
432 std::vector<std::string> fams(famIds.size());
434 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
436 std::string name2=getFamilyNameGivenId(*it1);
443 * Returns names of groups including a given family.
444 * \param [in] name - the name of the family of interest.
445 * \return std::vector<std::string> - a sequence of names of groups including the family.
447 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
449 std::vector<std::string> ret;
450 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
452 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
455 ret.push_back((*it1).first);
463 * Adds an existing family to groups.
464 * \param [in] famName - a name of family to add to \a grps.
465 * \param [in] grps - a sequence of group names to add the family in.
466 * \throw If a family named \a famName not yet exists.
468 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
470 std::string fName(famName);
471 const std::map<std::string,int>::const_iterator it=_families.find(fName);
472 if(it==_families.end())
474 std::vector<std::string> fams=getFamiliesNames();
475 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
476 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
477 throw INTERP_KERNEL::Exception(oss.str().c_str());
479 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
481 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
482 if(it2!=_groups.end())
483 (*it2).second.push_back(fName);
486 std::vector<std::string> grps2(1,fName);
493 * Returns names of all groups of \a this mesh.
494 * \return std::vector<std::string> - a sequence of group names.
496 std::vector<std::string> MEDFileMesh::getGroupsNames() const
498 std::vector<std::string> ret(_groups.size());
500 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
506 * Returns names of all families of \a this mesh.
507 * \return std::vector<std::string> - a sequence of family names.
509 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
511 std::vector<std::string> ret(_families.size());
513 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
519 * Returns names of all families of \a this mesh but like they would be in file.
520 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
521 * This method is only useful for aggressive users that want to have in their file a same family lying both on cells and on nodes. This is not a good idea for lisibility !
522 * For your information internaly in memory such families are renamed to have a nicer API.
524 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
526 std::vector<std::string> ret(getFamiliesNames());
527 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
531 std::string MEDFileMesh::GetMagicFamilyStr()
533 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
537 * Changes a name of every family, included in one group only, to be same as the group name.
538 * \throw If there are families with equal names in \a this mesh.
540 void MEDFileMesh::assignFamilyNameWithGroupName()
542 std::map<std::string, std::vector<std::string> > groups(_groups);
543 std::map<std::string,int> newFams;
544 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
546 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
547 if(grps.size()==1 && groups[grps[0]].size()==1)
549 if(newFams.find(grps[0])!=newFams.end())
551 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
552 throw INTERP_KERNEL::Exception(oss.str().c_str());
554 newFams[grps[0]]=(*it).second;
555 std::vector<std::string>& grps2=groups[grps[0]];
556 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
561 if(newFams.find((*it).first)!=newFams.end())
563 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
564 throw INTERP_KERNEL::Exception(oss.str().c_str());
566 newFams[(*it).first]=(*it).second;
574 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
576 * \return the removed groups.
578 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
580 std::vector<std::string> ret;
581 std::map<std::string, std::vector<std::string> > newGrps;
582 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
584 if((*it).second.empty())
585 ret.push_back((*it).first);
587 newGrps[(*it).first]=(*it).second;
595 * Removes a group from \a this mesh.
596 * \param [in] name - the name of the group to remove.
597 * \throw If no group with such a \a name exists.
599 void MEDFileMesh::removeGroup(const std::string& name)
601 std::string oname(name);
602 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
603 std::vector<std::string> grps=getGroupsNames();
604 if(it==_groups.end())
606 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
607 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
608 throw INTERP_KERNEL::Exception(oss.str().c_str());
614 * Removes a family from \a this mesh.
615 * \param [in] name - the name of the family to remove.
616 * \throw If no family with such a \a name exists.
618 void MEDFileMesh::removeFamily(const std::string& name)
620 std::string oname(name);
621 std::map<std::string, int >::iterator it=_families.find(oname);
622 std::vector<std::string> fams=getFamiliesNames();
623 if(it==_families.end())
625 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
626 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
627 throw INTERP_KERNEL::Exception(oss.str().c_str());
630 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
632 std::vector<std::string>& v=(*it3).second;
633 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
640 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
641 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
642 * family field whatever its level. This method also suppresses the orphan families.
644 * \return - The list of removed groups names.
646 * \sa MEDFileMesh::removeOrphanFamilies.
648 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
650 removeOrphanFamilies();
651 return removeEmptyGroups();
655 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
656 * 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.
658 * \return - The list of removed families names.
659 * \sa MEDFileMesh::removeOrphanGroups.
661 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
663 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
664 std::vector<std::string> ret;
665 if(!((DataArrayInt*)allFamIdsInUse))
667 ret=getFamiliesNames();
668 _families.clear(); _groups.clear();
671 std::map<std::string,int> famMap;
672 std::map<std::string, std::vector<std::string> > grps(_groups);
673 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
675 if(allFamIdsInUse->presenceOfValue((*it).second))
676 famMap[(*it).first]=(*it).second;
679 ret.push_back((*it).first);
680 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
681 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
683 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
684 std::vector<std::string>& famv=(*it3).second;
685 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
691 { _families=famMap; _groups=grps; }
696 * 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
697 * this family is orphan or not.
699 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
701 void MEDFileMesh::removeFamiliesReferedByNoGroups()
703 std::map<std::string,int> fams;
704 std::set<std::string> sfams;
705 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
706 sfams.insert((*it).first);
707 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
708 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
710 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
711 if(*it!=DFT_FAM_NAME)
712 _families.erase(*it);
716 * 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
717 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
718 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
720 * \sa MEDFileMesh::removeOrphanFamilies
722 void MEDFileMesh::rearrangeFamilies()
724 checkOrphanFamilyZero();
725 removeFamiliesReferedByNoGroups();
727 std::vector<int> levels(getNonEmptyLevelsExt());
728 std::set<int> idsRefed;
729 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
730 idsRefed.insert((*it).second);
731 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
733 const DataArrayInt *fams(0);
736 fams=getFamilyFieldAtLevel(*it);
738 catch(INTERP_KERNEL::Exception& e) { }
741 std::vector<bool> v(fams->getNumberOfTuples(),false);
742 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
743 fams->switchOnTupleEqualTo(*pt,v);
744 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
745 if(!unfetchedIds->empty())
747 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
748 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
749 setFamilyFieldArr(*it,newFams);
752 removeOrphanFamilies();
756 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
758 void MEDFileMesh::checkOrphanFamilyZero() const
760 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
762 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
764 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
765 throw INTERP_KERNEL::Exception(oss.str().c_str());
771 * Renames a group in \a this mesh.
772 * \param [in] oldName - a current name of the group to rename.
773 * \param [in] newName - a new group name.
774 * \throw If no group named \a oldName exists in \a this mesh.
775 * \throw If a group named \a newName already exists.
777 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
779 std::string oname(oldName);
780 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
781 std::vector<std::string> grps=getGroupsNames();
782 if(it==_groups.end())
784 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
785 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
786 throw INTERP_KERNEL::Exception(oss.str().c_str());
788 std::string nname(newName);
789 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
790 if(it2!=_groups.end())
792 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
793 throw INTERP_KERNEL::Exception(oss.str().c_str());
795 std::vector<std::string> cpy=(*it).second;
797 _groups[newName]=cpy;
801 * Changes an id of a family in \a this mesh.
802 * This method calls changeFamilyIdArr().
803 * \param [in] oldId - a current id of the family.
804 * \param [in] newId - a new family id.
806 void MEDFileMesh::changeFamilyId(int oldId, int newId)
808 changeFamilyIdArr(oldId,newId);
809 std::map<std::string,int> fam2;
810 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
812 if((*it).second==oldId)
813 fam2[(*it).first]=newId;
815 fam2[(*it).first]=(*it).second;
821 * Renames a family in \a this mesh.
822 * \param [in] oldName - a current name of the family to rename.
823 * \param [in] newName - a new family name.
824 * \throw If no family named \a oldName exists in \a this mesh.
825 * \throw If a family named \a newName already exists.
827 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
829 std::string oname(oldName);
830 std::map<std::string, int >::iterator it=_families.find(oname);
831 std::vector<std::string> fams=getFamiliesNames();
832 if(it==_families.end())
834 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
835 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
836 throw INTERP_KERNEL::Exception(oss.str().c_str());
838 std::string nname(newName);
839 std::map<std::string, int >::iterator it2=_families.find(nname);
840 if(it2!=_families.end())
842 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
843 throw INTERP_KERNEL::Exception(oss.str().c_str());
845 int cpy=(*it).second;
847 _families[newName]=cpy;
848 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
850 std::vector<std::string>& v=(*it3).second;
851 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
858 * Checks if \a this and another mesh contains the same families.
859 * \param [in] other - the mesh to compare with \a this one.
860 * \param [in,out] what - an unused parameter.
861 * \return bool - \c true if number of families and their ids are the same in the two
862 * meshes. Families with the id == \c 0 are not considered.
864 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
866 if(_families==other->_families)
868 std::map<std::string,int> fam0;
869 std::map<std::string,int> fam1;
870 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
872 fam0[(*it).first]=(*it).second;
873 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
875 fam1[(*it).first]=(*it).second;
880 * Checks if \a this and another mesh contains the same groups.
881 * \param [in] other - the mesh to compare with \a this one.
882 * \param [in,out] what - a string describing a difference of groups of the two meshes
883 * in case if this method returns \c false.
884 * \return bool - \c true if number of groups and families constituting them are the
885 * same in the two meshes.
887 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
889 if(_groups==other->_groups)
892 std::size_t sz=_groups.size();
893 if(sz!=other->_groups.size())
895 what="Groups differ because not same number !\n";
900 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
901 for(std::size_t i=0;i<sz && ret;i++,it1++)
903 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
904 if(it2!=other->_groups.end())
906 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
907 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
913 what="A group in first mesh exists not in other !\n";
919 std::ostringstream oss; oss << "Groups description differs :\n";
920 oss << "First group description :\n";
921 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
923 oss << " Group \"" << (*it).first << "\" on following families :\n";
924 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
925 oss << " \"" << *it2 << "\n";
927 oss << "Second group description :\n";
928 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
930 oss << " Group \"" << (*it).first << "\" on following families :\n";
931 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
932 oss << " \"" << *it2 << "\n";
940 * Checks if a group with a given name exists in \a this mesh.
941 * \param [in] groupName - the group name.
942 * \return bool - \c true the group \a groupName exists in \a this mesh.
944 bool MEDFileMesh::existsGroup(const std::string& groupName) const
946 std::string grpName(groupName);
947 return _groups.find(grpName)!=_groups.end();
951 * Checks if a family with a given id exists in \a this mesh.
952 * \param [in] famId - the family id.
953 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
955 bool MEDFileMesh::existsFamily(int famId) const
957 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
958 if((*it2).second==famId)
964 * Checks if a family with a given name exists in \a this mesh.
965 * \param [in] familyName - the family name.
966 * \return bool - \c true the family \a familyName exists in \a this mesh.
968 bool MEDFileMesh::existsFamily(const std::string& familyName) const
970 std::string fname(familyName);
971 return _families.find(fname)!=_families.end();
975 * Sets an id of a family.
976 * \param [in] familyName - the family name.
977 * \param [in] id - a new id of the family.
979 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
981 std::string fname(familyName);
985 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
987 std::string fname(familyName);
988 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
991 if((*it).first!=familyName)
993 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
994 throw INTERP_KERNEL::Exception(oss.str().c_str());
1001 * Adds a family to \a this mesh.
1002 * \param [in] familyName - a name of the family.
1003 * \param [in] famId - an id of the family.
1004 * \throw If a family with the same name or id already exists in \a this mesh.
1006 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1008 std::string fname(familyName);
1009 std::map<std::string,int>::const_iterator it=_families.find(fname);
1010 if(it==_families.end())
1012 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1013 if((*it2).second==famId)
1015 std::ostringstream oss;
1016 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1017 throw INTERP_KERNEL::Exception(oss.str().c_str());
1019 _families[fname]=famId;
1023 if((*it).second!=famId)
1025 std::ostringstream oss;
1026 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1027 throw INTERP_KERNEL::Exception(oss.str().c_str());
1033 * Creates a group including all mesh entities of given dimension.
1034 * \warning This method does \b not guarantee that the created group includes mesh
1035 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1036 * present in family fields of different dimensions. To assure this, call
1037 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1038 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1040 * \param [in] groupName - a name of the new group.
1041 * \throw If a group named \a groupName already exists.
1042 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1043 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1045 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1047 std::string grpName(groupName);
1048 std::vector<int> levs=getNonEmptyLevelsExt();
1049 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1051 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1052 oss << "Available relative ext levels are : ";
1053 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1054 throw INTERP_KERNEL::Exception(oss.str().c_str());
1056 if(existsGroup(groupName))
1058 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1059 oss << "Already existing groups are : ";
1060 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1061 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1062 throw INTERP_KERNEL::Exception(oss.str().c_str());
1064 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1066 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1067 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1068 std::vector<std::string> familiesOnWholeGroup;
1069 for(const int *it=famIds->begin();it!=famIds->end();it++)
1072 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1074 _groups[grpName]=familiesOnWholeGroup;
1078 * Ensures that given family ids do not present in family fields of dimensions different
1079 * than given ones. If a family id is present in the family fields of dimensions different
1080 * than the given ones, a new family is created and the whole data is updated accordingly.
1081 * \param [in] famIds - a sequence of family ids to check.
1082 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1083 * famIds should exclusively belong.
1084 * \return bool - \c true if no modification is done in \a this mesh by this method.
1086 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1088 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1089 std::vector<int> levs=getNonEmptyLevelsExt();
1090 std::set<int> levs2(levs.begin(),levs.end());
1091 std::vector<int> levsToTest;
1092 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1093 std::set<int> famIds2(famIds.begin(),famIds.end());
1096 if(!_families.empty())
1097 maxFamId=getMaxFamilyId()+1;
1098 std::vector<std::string> allFams=getFamiliesNames();
1099 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1101 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1104 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1105 std::vector<int> tmp;
1106 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1107 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1110 std::string famName=getFamilyNameGivenId(*it2);
1111 std::ostringstream oss; oss << "Family_" << maxFamId;
1112 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1113 addFamilyOnAllGroupsHaving(famName,zeName);
1114 _families[zeName]=maxFamId;
1115 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1124 * Adds a family to a given group in \a this mesh. If the group with a given name does
1125 * not exist, it is created.
1126 * \param [in] grpName - the name of the group to add the family in.
1127 * \param [in] famName - the name of the family to add to the group named \a grpName.
1128 * \throw If \a grpName or \a famName is an empty string.
1129 * \throw If no family named \a famName is present in \a this mesh.
1131 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1133 std::string grpn(grpName);
1134 std::string famn(famName);
1135 if(grpn.empty() || famn.empty())
1136 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1137 std::vector<std::string> fams=getFamiliesNames();
1138 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1140 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1141 oss << "Create this family or choose an existing one ! Existing fams are : ";
1142 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1143 throw INTERP_KERNEL::Exception(oss.str().c_str());
1145 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1146 if(it==_groups.end())
1148 _groups[grpn].push_back(famn);
1152 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1153 if(it2==(*it).second.end())
1154 (*it).second.push_back(famn);
1159 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1160 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1161 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1163 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1165 std::string famNameCpp(famName);
1166 std::string otherCpp(otherFamName);
1167 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1169 std::vector<std::string>& v=(*it).second;
1170 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1172 v.push_back(otherCpp);
1178 * \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).
1179 * \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)
1181 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1184 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1185 std::string grpName(ids->getName());
1187 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1188 ids->checkStrictlyMonotonic(true);
1189 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
1190 std::vector<std::string> grpsNames=getGroupsNames();
1191 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1193 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1194 throw INTERP_KERNEL::Exception(oss.str().c_str());
1196 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1197 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1198 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1199 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1200 std::vector<int> familyIds;
1201 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
1202 int maxVal=getTheMaxAbsFamilyId()+1;
1203 std::map<std::string,int> families(_families);
1204 std::map<std::string, std::vector<std::string> > groups(_groups);
1205 std::vector<std::string> fams;
1206 bool created(false);
1207 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1209 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
1210 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1211 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
1212 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1215 bool isFamPresent=false;
1216 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1217 isFamPresent=(*itl)->presenceOfValue(*famId);
1219 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1222 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1223 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1224 fams.push_back(locFamName);
1225 if(existsFamily(*famId))
1227 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1228 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1231 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1235 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1236 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1237 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1238 if(existsFamily(*famId))
1240 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1241 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1246 for(std::size_t i=0;i<familyIds.size();i++)
1248 DataArrayInt *da=idsPerfamiliyIds[i];
1249 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1253 _groups[grpName]=fams;
1256 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1258 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1261 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1263 std::string fam(familyNameToChange);
1264 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1266 std::vector<std::string>& fams((*it).second);
1267 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1271 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1277 * Returns a name of the family having a given id or, if no such a family exists, creates
1278 * a new uniquely named family and returns its name.
1279 * \param [in] id - the id of the family whose name is required.
1280 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1281 * \return std::string - the name of the existing or the created family.
1282 * \throw If it is not possible to create a unique family name.
1284 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1286 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1290 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1291 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1292 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1293 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1295 * This method will throws an exception if it is not possible to create a unique family name.
1297 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1299 std::vector<std::string> famAlreadyExisting(families.size());
1301 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1303 if((*it).second!=id)
1305 famAlreadyExisting[ii]=(*it).first;
1314 std::ostringstream oss; oss << "Family_" << id;
1315 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1321 * Sets names and ids of all families in \a this mesh.
1322 * \param [in] info - a map of a family name to a family id.
1324 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1330 * Sets names of all groups and families constituting them in \a this mesh.
1331 * \param [in] info - a map of a group name to a vector of names of families
1332 * constituting the group.
1334 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1340 * Returns an id of the family having a given name.
1341 * \param [in] name - the name of the family of interest.
1342 * \return int - the id of the family of interest.
1343 * \throw If no family with such a \a name exists.
1345 int MEDFileMesh::getFamilyId(const std::string& name) const
1347 std::string oname(name);
1348 std::map<std::string, int>::const_iterator it=_families.find(oname);
1349 std::vector<std::string> fams=getFamiliesNames();
1350 if(it==_families.end())
1352 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1353 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1354 throw INTERP_KERNEL::Exception(oss.str().c_str());
1356 return (*it).second;
1360 * Returns ids of the families having given names.
1361 * \param [in] fams - a sequence of the names of families of interest.
1362 * \return std::vector<int> - a sequence of the ids of families of interest.
1363 * \throw If \a fams contains a name of an inexistent family.
1365 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1367 std::vector<int> ret(fams.size());
1369 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1371 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1372 if(it2==_families.end())
1374 std::vector<std::string> fams2=getFamiliesNames();
1375 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1376 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1377 throw INTERP_KERNEL::Exception(oss.str().c_str());
1379 ret[i]=(*it2).second;
1385 * Returns a maximal abs(id) of families in \a this mesh.
1386 * \return int - the maximal norm of family id.
1387 * \throw If there are no families in \a this mesh.
1389 int MEDFileMesh::getMaxAbsFamilyId() const
1391 if(_families.empty())
1392 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1393 int ret=-std::numeric_limits<int>::max();
1394 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1396 ret=std::max(std::abs((*it).second),ret);
1402 * Returns a maximal id of families in \a this mesh.
1403 * \return int - the maximal family id.
1404 * \throw If there are no families in \a this mesh.
1406 int MEDFileMesh::getMaxFamilyId() const
1408 if(_families.empty())
1409 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1410 int ret=-std::numeric_limits<int>::max();
1411 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1413 ret=std::max((*it).second,ret);
1419 * Returns a minimal id of families in \a this mesh.
1420 * \return int - the minimal family id.
1421 * \throw If there are no families in \a this mesh.
1423 int MEDFileMesh::getMinFamilyId() const
1425 if(_families.empty())
1426 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1427 int ret=std::numeric_limits<int>::max();
1428 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1430 ret=std::min((*it).second,ret);
1436 * Returns a maximal id of families in \a this mesh. Not only named families are
1437 * considered but all family fields as well.
1438 * \return int - the maximal family id.
1440 int MEDFileMesh::getTheMaxAbsFamilyId() const
1442 int m1=-std::numeric_limits<int>::max();
1443 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1444 m1=std::max(std::abs((*it).second),m1);
1445 int m2=getMaxAbsFamilyIdInArrays();
1446 return std::max(m1,m2);
1450 * Returns a maximal id of families in \a this mesh. Not only named families are
1451 * considered but all family fields as well.
1452 * \return int - the maximal family id.
1454 int MEDFileMesh::getTheMaxFamilyId() const
1456 int m1=-std::numeric_limits<int>::max();
1457 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1458 m1=std::max((*it).second,m1);
1459 int m2=getMaxFamilyIdInArrays();
1460 return std::max(m1,m2);
1464 * Returns a minimal id of families in \a this mesh. Not only named families are
1465 * considered but all family fields as well.
1466 * \return int - the minimal family id.
1468 int MEDFileMesh::getTheMinFamilyId() const
1470 int m1=std::numeric_limits<int>::max();
1471 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1472 m1=std::min((*it).second,m1);
1473 int m2=getMinFamilyIdInArrays();
1474 return std::min(m1,m2);
1478 * This method only considers the maps. The contain of family array is ignored here.
1480 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1482 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1484 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1486 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1487 v.insert((*it).second);
1488 ret->alloc((int)v.size(),1);
1489 std::copy(v.begin(),v.end(),ret->getPointer());
1494 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1496 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1498 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1500 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1501 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1502 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1504 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1505 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1506 if((DataArrayInt *) ret)
1507 ret=dv->buildUnion(ret);
1515 * true is returned if no modification has been needed. false if family
1516 * renumbering has been needed.
1518 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1520 std::vector<int> levs=getNonEmptyLevelsExt();
1521 std::set<int> allFamIds;
1522 int maxId=getMaxFamilyId()+1;
1523 std::map<int,std::vector<int> > famIdsToRenum;
1524 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1526 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1529 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1531 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1533 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1535 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1538 if(famIdsToRenum.empty())
1540 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1541 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1543 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1544 int *famIdsToChange=fam->getPointer();
1545 std::map<int,int> ren;
1546 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1548 if(allIds->presenceOfValue(*it3))
1550 std::string famName=getFamilyNameGivenId(*it3);
1551 std::vector<std::string> grps=getGroupsOnFamily(famName);
1554 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1555 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1556 addFamilyOnGrp((*it4),newFam);
1559 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1560 for(const int *id=ids->begin();id!=ids->end();id++)
1561 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1567 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1568 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1569 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1570 * This method will throw an exception if a same family id is detected in different level.
1571 * \warning This policy is the opposite of those in MED file documentation ...
1573 void MEDFileMesh::normalizeFamIdsTrio()
1575 ensureDifferentFamIdsPerLevel();
1576 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1577 std::vector<int> levs=getNonEmptyLevelsExt();
1578 std::set<int> levsS(levs.begin(),levs.end());
1579 std::set<std::string> famsFetched;
1580 std::map<std::string,int> families;
1581 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1584 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1588 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1589 std::map<int,int> ren;
1590 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1592 int nbOfTuples=fam->getNumberOfTuples();
1593 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1594 for(int *w=start;w!=start+nbOfTuples;w++)
1596 for(const int *it=tmp->begin();it!=tmp->end();it++)
1598 if(allIds->presenceOfValue(*it))
1600 std::string famName=getFamilyNameGivenId(*it);
1601 families[famName]=ren[*it];
1602 famsFetched.insert(famName);
1607 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1610 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1614 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1615 std::map<int,int> ren;
1616 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1618 int nbOfTuples=fam->getNumberOfTuples();
1619 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1620 for(int *w=start;w!=start+nbOfTuples;w++)
1622 for(const int *it=tmp->begin();it!=tmp->end();it++)
1624 if(allIds->presenceOfValue(*it))
1626 std::string famName=getFamilyNameGivenId(*it);
1627 families[famName]=ren[*it];
1628 famsFetched.insert(famName);
1633 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1635 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1638 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1639 fam->fillWithZero();
1640 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1641 if(allIds->presenceOfValue(*it3))
1643 std::string famName=getFamilyNameGivenId(*it3);
1644 families[famName]=0;
1645 famsFetched.insert(famName);
1650 std::vector<std::string> allFams=getFamiliesNames();
1651 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1652 std::set<std::string> unFetchedIds;
1653 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1654 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1655 families[*it4]=_families[*it4];
1660 * This method normalizes fam id with the following policy.
1661 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1662 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1663 * This method will throw an exception if a same family id is detected in different level.
1665 void MEDFileMesh::normalizeFamIdsMEDFile()
1667 ensureDifferentFamIdsPerLevel();
1668 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1669 std::vector<int> levs=getNonEmptyLevelsExt();
1670 std::set<int> levsS(levs.begin(),levs.end());
1671 std::set<std::string> famsFetched;
1672 std::map<std::string,int> families;
1674 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1677 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1680 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1681 std::map<int,int> ren;
1682 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1684 int nbOfTuples=fam->getNumberOfTuples();
1685 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1686 for(int *w=start;w!=start+nbOfTuples;w++)
1688 for(const int *it=tmp->begin();it!=tmp->end();it++)
1690 if(allIds->presenceOfValue(*it))
1692 std::string famName=getFamilyNameGivenId(*it);
1693 families[famName]=ren[*it];
1694 famsFetched.insert(famName);
1700 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1702 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1705 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1706 std::map<int,int> ren;
1707 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1709 int nbOfTuples=fam->getNumberOfTuples();
1710 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1711 for(int *w=start;w!=start+nbOfTuples;w++)
1713 for(const int *it=tmp->begin();it!=tmp->end();it++)
1715 if(allIds->presenceOfValue(*it))
1717 std::string famName=getFamilyNameGivenId(*it);
1718 families[famName]=ren[*it];
1719 famsFetched.insert(famName);
1725 std::vector<std::string> allFams=getFamiliesNames();
1726 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1727 std::set<std::string> unFetchedIds;
1728 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1729 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1730 families[*it4]=_families[*it4];
1735 * Returns a name of the family by its id. If there are several families having the given
1736 * id, the name first in lexical order is returned.
1737 * \param [in] id - the id of the family whose name is required.
1738 * \return std::string - the name of the found family.
1739 * \throw If no family with the given \a id exists.
1741 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1743 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1744 if((*it).second==id)
1746 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1747 throw INTERP_KERNEL::Exception(oss.str().c_str());
1751 * Returns a string describing \a this mesh. This description includes the mesh name and
1752 * the mesh description string.
1753 * \return std::string - the mesh information string.
1755 std::string MEDFileMesh::simpleRepr() const
1757 std::ostringstream oss;
1758 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1759 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1760 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1765 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1766 * an empty one is created.
1768 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1770 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1773 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
1774 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1775 arr->fillWithZero();
1776 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1777 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1781 * Returns ids of mesh entities contained in a given group of a given dimension.
1782 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1784 * \param [in] grp - the name of the group of interest.
1785 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1786 * returned instead of ids.
1787 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1788 * numbers, if available and required, of mesh entities of the group. The caller
1789 * is to delete this array using decrRef() as it is no more needed.
1790 * \throw If the name of a nonexistent group is specified.
1791 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1793 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1795 std::vector<std::string> tmp(1);
1797 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1803 * Returns ids of mesh entities contained in given groups of a given dimension.
1804 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1806 * \param [in] grps - the names of the groups of interest.
1807 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1808 * returned instead of ids.
1809 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1810 * numbers, if available and required, of mesh entities of the groups. The caller
1811 * is to delete this array using decrRef() as it is no more needed.
1812 * \throw If the name of a nonexistent group is present in \a grps.
1813 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1815 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1817 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1818 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1822 * Returns ids of mesh entities contained in a given family of a given dimension.
1823 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1825 * \param [in] fam - the name of the family of interest.
1826 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1827 * returned instead of ids.
1828 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1829 * numbers, if available and required, of mesh entities of the family. The caller
1830 * is to delete this array using decrRef() as it is no more needed.
1831 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1833 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1835 std::vector<std::string> tmp(1);
1837 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1843 * Returns ids of nodes contained in a given group.
1844 * \param [in] grp - the name of the group of interest.
1845 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1846 * returned instead of ids.
1847 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1848 * numbers, if available and required, of nodes of the group. The caller
1849 * is to delete this array using decrRef() as it is no more needed.
1850 * \throw If the name of a nonexistent group is specified.
1851 * \throw If the family field is missing for nodes.
1853 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1855 std::vector<std::string> tmp(1);
1857 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1863 * Returns ids of nodes contained in given groups.
1864 * \param [in] grps - the names of the groups of interest.
1865 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1866 * returned instead of ids.
1867 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1868 * numbers, if available and required, of nodes of the groups. The caller
1869 * is to delete this array using decrRef() as it is no more needed.
1870 * \throw If the name of a nonexistent group is present in \a grps.
1871 * \throw If the family field is missing for nodes.
1873 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1875 return getGroupsArr(1,grps,renum);
1879 * Returns ids of nodes contained in a given group.
1880 * \param [in] grp - the name of the group of interest.
1881 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1882 * returned instead of ids.
1883 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1884 * numbers, if available and required, of nodes of the group. The caller
1885 * is to delete this array using decrRef() as it is no more needed.
1886 * \throw If the name of a nonexistent group is specified.
1887 * \throw If the family field is missing for nodes.
1889 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1891 std::vector<std::string> tmp(1);
1893 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1899 * Returns ids of nodes contained in given families.
1900 * \param [in] fams - the names of the families of interest.
1901 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1902 * returned instead of ids.
1903 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1904 * numbers, if available and required, of nodes of the families. The caller
1905 * is to delete this array using decrRef() as it is no more needed.
1906 * \throw If the family field is missing for nodes.
1908 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1910 return getFamiliesArr(1,fams,renum);
1914 * Adds groups of given dimension and creates corresponding families and family fields
1915 * given ids of mesh entities of each group.
1916 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1917 * \param [in] grps - a sequence of arrays of ids each describing a group.
1918 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1920 * \throw If names of some groups in \a grps are equal.
1921 * \throw If \a grps includes a group with an empty name.
1922 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1923 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1925 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1929 std::set<std::string> grpsName;
1930 std::vector<std::string> grpsName2(grps.size());
1933 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1935 grpsName.insert((*it)->getName());
1936 grpsName2[i]=(*it)->getName();
1938 if(grpsName.size()!=grps.size())
1939 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1940 if(grpsName.find(std::string(""))!=grpsName.end())
1941 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1942 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1943 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1944 std::vector< std::vector<int> > fidsOfGroups;
1947 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1951 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1952 for(unsigned int ii=0;ii<grps.size();ii++)
1954 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1955 grps2[ii]->setName(grps[ii]->getName());
1957 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1958 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1961 if(!_families.empty())
1962 offset=getMaxAbsFamilyId()+1;
1963 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1964 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1965 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1966 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1970 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1971 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1972 * For the moment, the two last input parameters are not taken into account.
1974 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1976 std::map<int,std::string> famInv;
1977 for(const int *it=famIds->begin();it!=famIds->end();it++)
1979 std::ostringstream oss;
1980 oss << "Family_" << (*it);
1981 _families[oss.str()]=(*it);
1982 famInv[*it]=oss.str();
1985 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1987 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1989 _groups[grpNames[i]].push_back(famInv[*it2]);
1994 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1996 std::vector<int> levs(getNonEmptyLevels());
1997 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1998 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2000 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2001 ret.insert(ret.end(),elts.begin(),elts.end());
2006 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2008 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
2009 return mLev->getDistributionOfTypes();
2012 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2014 loadLL(fid,mName,dt,it,mrs);
2015 loadJointsFromFile(fid);
2016 loadEquivalences(fid);
2019 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2021 famArr->applyLin(offset>0?1:-1,offset,0);
2022 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2025 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2026 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2031 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2032 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2033 * If this method fails to find such a name it will throw an exception.
2035 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2038 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2041 std::size_t len=nameTry.length();
2042 for(std::size_t ii=1;ii<len;ii++)
2044 std::string tmp=nameTry.substr(ii,len-ii);
2045 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2051 for(std::size_t i=1;i<30;i++)
2053 std::string tmp1(nameTry.at(0),i);
2055 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2061 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2063 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2065 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2068 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2070 std::size_t nbOfChunks=code.size()/3;
2071 if(code.size()%3!=0)
2072 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2074 for(std::size_t i=0;i<nbOfChunks;i++)
2083 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2084 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2085 * If _name is not empty and that 'm' has the same name nothing is done.
2086 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2088 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2091 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2096 std::string name(m->getName());
2101 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2102 oss << name << "' ! Names must match !";
2103 throw INTERP_KERNEL::Exception(oss.str().c_str());
2107 if(_desc_name.empty())
2108 _desc_name=m->getDescription();
2111 std::string name(m->getDescription());
2114 if(_desc_name!=name)
2116 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2117 oss << name << "' ! Names must match !";
2118 throw INTERP_KERNEL::Exception(oss.str().c_str());
2124 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2126 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2127 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2129 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2130 oss << " - Groups lying on this family : ";
2131 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2132 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2133 oss << std::endl << std::endl;
2138 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2139 * file. The mesh to load is specified by its name and numbers of a time step and an
2141 * \param [in] fileName - the name of MED file to read.
2142 * \param [in] mName - the name of the mesh to read.
2143 * \param [in] dt - the number of a time step.
2144 * \param [in] it - the number of an iteration.
2145 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2146 * mesh using decrRef() as it is no more needed.
2147 * \throw If the file is not readable.
2148 * \throw If there is no mesh with given attributes in the file.
2149 * \throw If the mesh in the file is not an unstructured one.
2151 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2153 MEDFileUtilities::CheckFileForRead(fileName);
2154 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2155 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2159 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2160 * file. The first mesh in the file is loaded.
2161 * \param [in] fileName - the name of MED file to read.
2162 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2163 * mesh using decrRef() as it is no more needed.
2164 * \throw If the file is not readable.
2165 * \throw If there is no meshes in the file.
2166 * \throw If the mesh in the file is not an unstructured one.
2168 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2170 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2173 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2174 throw INTERP_KERNEL::Exception(oss.str().c_str());
2176 MEDFileUtilities::CheckFileForRead(fileName);
2177 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2179 ParaMEDMEM::MEDCouplingMeshType meshType;
2181 ParaMEDMEM::MEDCouplingAxisType dummy3;
2182 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2183 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2187 * Returns an empty instance of MEDFileUMesh.
2188 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2189 * mesh using decrRef() as it is no more needed.
2191 MEDFileUMesh *MEDFileUMesh::New()
2193 return new MEDFileUMesh;
2197 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2198 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2199 * \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.
2200 * 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
2201 * at most the memory consumtion.
2203 * \param [in] fileName - the name of the file.
2204 * \param [in] mName - the name of the mesh to be read.
2205 * \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.
2206 * \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.
2207 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2208 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2209 * \param [in] mrs - the request for what to be loaded.
2210 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2212 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)
2214 MEDFileUtilities::CheckFileForRead(fileName);
2215 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2216 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2220 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2221 * This method is \b NOT wrapped into python.
2223 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)
2225 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2226 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2230 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2232 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2233 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2237 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2239 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2240 ret.push_back((const DataArrayDouble*)_coords);
2241 ret.push_back((const DataArrayInt *)_fam_coords);
2242 ret.push_back((const DataArrayInt *)_num_coords);
2243 ret.push_back((const DataArrayInt *)_rev_num_coords);
2244 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2245 ret.push_back((const PartDefinition *)_part_coords);
2246 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2247 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2251 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2253 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2257 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2259 return new MEDFileUMesh;
2262 MEDFileMesh *MEDFileUMesh::deepCpy() const
2264 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2265 ret->deepCpyEquivalences(*this);
2266 if((const DataArrayDouble*)_coords)
2267 ret->_coords=_coords->deepCpy();
2268 if((const DataArrayInt*)_fam_coords)
2269 ret->_fam_coords=_fam_coords->deepCpy();
2270 if((const DataArrayInt*)_num_coords)
2271 ret->_num_coords=_num_coords->deepCpy();
2272 if((const DataArrayInt*)_rev_num_coords)
2273 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2274 if((const DataArrayAsciiChar*)_name_coords)
2275 ret->_name_coords=_name_coords->deepCpy();
2277 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2279 if((const MEDFileUMeshSplitL1 *)(*it))
2280 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2282 if((const PartDefinition*)_part_coords)
2283 ret->_part_coords=_part_coords->deepCpy();
2288 * Checks if \a this and another mesh are equal.
2289 * \param [in] other - the mesh to compare with.
2290 * \param [in] eps - a precision used to compare real values.
2291 * \param [in,out] what - the string returning description of unequal data.
2292 * \return bool - \c true if the meshes are equal, \c false, else.
2294 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2296 if(!MEDFileMesh::isEqual(other,eps,what))
2298 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2301 what="Mesh types differ ! This is unstructured and other is NOT !";
2304 clearNonDiscrAttributes();
2305 otherC->clearNonDiscrAttributes();
2306 const DataArrayDouble *coo1=_coords;
2307 const DataArrayDouble *coo2=otherC->_coords;
2308 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2310 what="Mismatch of coordinates ! One is defined and not other !";
2315 bool ret=coo1->isEqual(*coo2,eps);
2318 what="Coords differ !";
2322 const DataArrayInt *famc1=_fam_coords;
2323 const DataArrayInt *famc2=otherC->_fam_coords;
2324 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2326 what="Mismatch of families arr on nodes ! One is defined and not other !";
2331 bool ret=famc1->isEqual(*famc2);
2334 what="Families arr on node differ !";
2338 const DataArrayInt *numc1=_num_coords;
2339 const DataArrayInt *numc2=otherC->_num_coords;
2340 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2342 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2347 bool ret=numc1->isEqual(*numc2);
2350 what="Numbering arr on node differ !";
2354 const DataArrayAsciiChar *namec1=_name_coords;
2355 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2356 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2358 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2363 bool ret=namec1->isEqual(*namec2);
2366 what="Names arr on node differ !";
2370 if(_ms.size()!=otherC->_ms.size())
2372 what="Number of levels differs !";
2375 std::size_t sz=_ms.size();
2376 for(std::size_t i=0;i<sz;i++)
2378 const MEDFileUMeshSplitL1 *s1=_ms[i];
2379 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2380 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2382 what="Mismatch of presence of sub levels !";
2387 bool ret=s1->isEqual(s2,eps,what);
2392 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2395 if((!pd0 && pd1) || (pd0 && !pd1))
2397 what=std::string("node part def is defined only for one among this or other !");
2400 return pd0->isEqual(pd1,what);
2404 * Clears redundant attributes of incorporated data arrays.
2406 void MEDFileUMesh::clearNonDiscrAttributes() const
2408 MEDFileMesh::clearNonDiscrAttributes();
2409 const DataArrayDouble *coo1=_coords;
2411 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2412 const DataArrayInt *famc1=_fam_coords;
2414 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2415 const DataArrayInt *numc1=_num_coords;
2417 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2418 const DataArrayAsciiChar *namc1=_name_coords;
2420 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2421 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2423 const MEDFileUMeshSplitL1 *tmp=(*it);
2425 tmp->clearNonDiscrAttributes();
2429 void MEDFileUMesh::setName(const std::string& name)
2431 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2432 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2433 (*it)->setName(name);
2434 MEDFileMesh::setName(name);
2437 MEDFileUMesh::MEDFileUMesh()
2441 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2444 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2446 catch(INTERP_KERNEL::Exception& e)
2452 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2453 * See MEDFileUMesh::LoadPartOf for detailed description.
2457 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)
2459 MEDFileUMeshL2 loaderl2;
2460 ParaMEDMEM::MEDCouplingMeshType meshType;
2463 ParaMEDMEM::MEDCouplingAxisType dummy3;
2464 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2465 if(meshType!=UNSTRUCTURED)
2467 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2468 throw INTERP_KERNEL::Exception(oss.str().c_str());
2470 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2471 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2475 * \brief Write joints in a file
2477 void MEDFileMesh::writeJoints(med_idt fid) const
2479 if ( (const MEDFileJoints*) _joints )
2480 _joints->write(fid);
2484 * \brief Load joints in a file or use provided ones
2486 //================================================================================
2488 * \brief Load joints in a file or use provided ones
2489 * \param [in] fid - MED file descriptor
2490 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2491 * Usually this joints are those just read by another iteration
2492 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2494 //================================================================================
2496 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2498 if ( toUseInstedOfReading )
2499 setJoints( toUseInstedOfReading );
2501 _joints = MEDFileJoints::New( fid, _name );
2504 void MEDFileMesh::loadEquivalences(med_idt fid)
2506 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2508 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2511 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2513 const MEDFileEquivalences *equiv(other._equiv);
2515 _equiv=equiv->deepCpy(this);
2518 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2520 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2521 if(!thisEq && !otherEq)
2523 if(thisEq && otherEq)
2524 return thisEq->isEqual(otherEq,what);
2527 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2532 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2534 const MEDFileEquivalences *equiv(_equiv);
2537 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2538 _equiv->getRepr(oss);
2542 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2544 int MEDFileMesh::getNumberOfJoints() const
2546 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2550 * \brief Return joints with all adjacent mesh domains
2552 MEDFileJoints * MEDFileMesh::getJoints() const
2554 return const_cast<MEDFileJoints*>(& (*_joints));
2557 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2559 if ( joints != _joints )
2568 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2570 * \sa loadPartUMeshFromFile
2572 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2574 MEDFileUMeshL2 loaderl2;
2575 ParaMEDMEM::MEDCouplingMeshType meshType;
2578 ParaMEDMEM::MEDCouplingAxisType axType;
2579 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2581 if(meshType!=UNSTRUCTURED)
2583 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2584 throw INTERP_KERNEL::Exception(oss.str().c_str());
2586 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2587 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2590 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2592 int lev=loaderl2.getNumberOfLevels();
2594 for(int i=0;i<lev;i++)
2596 if(!loaderl2.emptyLev(i))
2597 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2601 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2603 setName(loaderl2.getName());
2604 setDescription(loaderl2.getDescription());
2605 setUnivName(loaderl2.getUnivName());
2606 setIteration(loaderl2.getIteration());
2607 setOrder(loaderl2.getOrder());
2608 setTimeValue(loaderl2.getTime());
2609 setTimeUnit(loaderl2.getTimeUnit());
2610 _coords=loaderl2.getCoords();
2611 if(!mrs || mrs->isNodeFamilyFieldReading())
2612 _fam_coords=loaderl2.getCoordsFamily();
2613 if(!mrs || mrs->isNodeNumFieldReading())
2614 _num_coords=loaderl2.getCoordsNum();
2615 if(!mrs || mrs->isNodeNameFieldReading())
2616 _name_coords=loaderl2.getCoordsName();
2617 _part_coords=loaderl2.getPartDefOfCoo();
2621 MEDFileUMesh::~MEDFileUMesh()
2625 void MEDFileUMesh::writeLL(med_idt fid) const
2627 const DataArrayDouble *coo=_coords;
2628 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2629 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2630 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2631 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2632 int spaceDim=coo?coo->getNumberOfComponents():0;
2635 mdim=getMeshDimension();
2636 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2637 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2638 for(int i=0;i<spaceDim;i++)
2640 std::string info=coo->getInfoOnComponent(i);
2642 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2643 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
2644 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
2646 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),comp,unit));
2648 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2649 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2650 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2651 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2652 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2653 (*it)->write(fid,meshName,mdim);
2654 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2658 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2659 * \return std::vector<int> - a sequence of the relative dimensions.
2661 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2663 std::vector<int> ret;
2665 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2666 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2673 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2674 * \return std::vector<int> - a sequence of the relative dimensions.
2676 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2678 std::vector<int> ret0=getNonEmptyLevels();
2679 if((const DataArrayDouble *) _coords)
2681 std::vector<int> ret(ret0.size()+1);
2683 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2689 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2691 std::vector<int> ret;
2692 const DataArrayInt *famCoo(_fam_coords);
2696 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2698 const MEDFileUMeshSplitL1 *cur(*it);
2700 if(cur->getFamilyField())
2706 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2708 std::vector<int> ret;
2709 const DataArrayInt *numCoo(_num_coords);
2713 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2715 const MEDFileUMeshSplitL1 *cur(*it);
2717 if(cur->getNumberField())
2723 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2725 std::vector<int> ret;
2726 const DataArrayAsciiChar *nameCoo(_name_coords);
2730 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2732 const MEDFileUMeshSplitL1 *cur(*it);
2734 if(cur->getNameField())
2741 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2742 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2743 * \param [in] grp - the name of the group of interest.
2744 * \return std::vector<int> - a sequence of the relative dimensions.
2746 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2748 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2749 return getFamsNonEmptyLevels(fams);
2753 * Returns all relative mesh levels (including nodes) where a given group is defined.
2754 * \param [in] grp - the name of the group of interest.
2755 * \return std::vector<int> - a sequence of the relative dimensions.
2757 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2759 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2760 return getFamsNonEmptyLevelsExt(fams);
2764 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2765 * To include nodes, call getFamNonEmptyLevelsExt() method.
2766 * \param [in] fam - the name of the family of interest.
2767 * \return std::vector<int> - a sequence of the relative dimensions.
2769 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2771 std::vector<std::string> fams(1,std::string(fam));
2772 return getFamsNonEmptyLevels(fams);
2776 * Returns all relative mesh levels (including nodes) where a given family is defined.
2777 * \param [in] fam - the name of the family of interest.
2778 * \return std::vector<int> - a sequence of the relative dimensions.
2780 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2782 std::vector<std::string> fams(1,std::string(fam));
2783 return getFamsNonEmptyLevelsExt(fams);
2787 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2788 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2789 * \param [in] grps - a sequence of names of the groups of interest.
2790 * \return std::vector<int> - a sequence of the relative dimensions.
2792 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2794 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2795 return getFamsNonEmptyLevels(fams);
2799 * Returns all relative mesh levels (including nodes) where given groups are defined.
2800 * \param [in] grps - a sequence of names of the groups of interest.
2801 * \return std::vector<int> - a sequence of the relative dimensions.
2803 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2805 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2806 return getFamsNonEmptyLevelsExt(fams);
2810 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2811 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2812 * \param [in] fams - the name of the family of interest.
2813 * \return std::vector<int> - a sequence of the relative dimensions.
2815 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2817 std::vector<int> ret;
2818 std::vector<int> levs=getNonEmptyLevels();
2819 std::vector<int> famIds=getFamiliesIds(fams);
2820 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2821 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2827 * Returns all relative mesh levels (including nodes) where given families are defined.
2828 * \param [in] fams - the names of the families of interest.
2829 * \return std::vector<int> - a sequence of the relative dimensions.
2831 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2833 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2834 const DataArrayInt *famCoords=_fam_coords;
2837 std::vector<int> famIds=getFamiliesIds(fams);
2838 if(famCoords->presenceOfValue(famIds))
2840 std::vector<int> ret(ret0.size()+1);
2842 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2850 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2851 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2852 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2855 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2857 std::vector<std::string> ret;
2858 std::vector<std::string> allGrps=getGroupsNames();
2859 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2861 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2862 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2868 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2870 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2871 if((const DataArrayInt *)_fam_coords)
2873 int val=_fam_coords->getMaxValue(tmp);
2874 ret=std::max(ret,std::abs(val));
2876 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2878 if((const MEDFileUMeshSplitL1 *)(*it))
2880 const DataArrayInt *da=(*it)->getFamilyField();
2883 int val=da->getMaxValue(tmp);
2884 ret=std::max(ret,std::abs(val));
2891 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2893 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2894 if((const DataArrayInt *)_fam_coords)
2896 int val=_fam_coords->getMaxValue(tmp);
2897 ret=std::max(ret,val);
2899 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2901 if((const MEDFileUMeshSplitL1 *)(*it))
2903 const DataArrayInt *da=(*it)->getFamilyField();
2906 int val=da->getMaxValue(tmp);
2907 ret=std::max(ret,val);
2914 int MEDFileUMesh::getMinFamilyIdInArrays() const
2916 int ret=std::numeric_limits<int>::max(),tmp=-1;
2917 if((const DataArrayInt *)_fam_coords)
2919 int val=_fam_coords->getMinValue(tmp);
2920 ret=std::min(ret,val);
2922 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2924 if((const MEDFileUMeshSplitL1 *)(*it))
2926 const DataArrayInt *da=(*it)->getFamilyField();
2929 int val=da->getMinValue(tmp);
2930 ret=std::min(ret,val);
2938 * Returns the dimension on cells in \a this mesh.
2939 * \return int - the mesh dimension.
2940 * \throw If there are no cells in this mesh.
2942 int MEDFileUMesh::getMeshDimension() const
2945 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2946 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2947 return (*it)->getMeshDimension()+lev;
2948 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2952 * Returns the space dimension of \a this mesh that is equal to number of components in
2953 * the node coordinates array.
2954 * \return int - the space dimension of \a this mesh.
2955 * \throw If the node coordinates array is not available.
2957 int MEDFileUMesh::getSpaceDimension() const
2959 const DataArrayDouble *coo=_coords;
2961 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2962 return coo->getNumberOfComponents();
2966 * Returns a string describing \a this mesh.
2967 * \return std::string - the mesh information string.
2969 std::string MEDFileUMesh::simpleRepr() const
2971 std::ostringstream oss;
2972 oss << MEDFileMesh::simpleRepr();
2973 const DataArrayDouble *coo=_coords;
2974 oss << "- The dimension of the space is ";
2975 static const char MSG1[]= "*** NO COORDS SET ***";
2976 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2978 oss << _coords->getNumberOfComponents() << std::endl;
2980 oss << MSG1 << std::endl;
2981 oss << "- Type of the mesh : UNSTRUCTURED\n";
2982 oss << "- Number of nodes : ";
2984 oss << _coords->getNumberOfTuples() << std::endl;
2986 oss << MSG1 << std::endl;
2987 std::size_t nbOfLev=_ms.size();
2988 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2989 for(std::size_t i=0;i<nbOfLev;i++)
2991 const MEDFileUMeshSplitL1 *lev=_ms[i];
2992 oss << " - Level #" << -((int) i) << " has dimension : ";
2995 oss << lev->getMeshDimension() << std::endl;
2996 lev->simpleRepr(oss);
2999 oss << MSG2 << std::endl;
3001 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3004 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3005 oss << "- Names of coordinates :" << std::endl;
3006 std::vector<std::string> vars=coo->getVarsOnComponent();
3007 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3008 oss << std::endl << "- Units of coordinates : " << std::endl;
3009 std::vector<std::string> units=coo->getUnitsOnComponent();
3010 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3012 oss << std::endl << std::endl;
3014 getEquivalencesRepr(oss);
3019 * Returns a full textual description of \a this mesh.
3020 * \return std::string - the string holding the mesh description.
3022 std::string MEDFileUMesh::advancedRepr() const
3024 return simpleRepr();
3028 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3029 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3030 * \return int - the number of entities.
3031 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3033 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3035 if(meshDimRelToMaxExt==1)
3037 if(!((const DataArrayDouble *)_coords))
3038 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3039 return _coords->getNumberOfTuples();
3041 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3045 * Returns the family field for mesh entities of a given dimension.
3046 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3047 * \return const DataArrayInt * - the family field. It is an array of ids of families
3048 * each mesh entity belongs to. It can be \c NULL.
3050 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3052 if(meshDimRelToMaxExt==1)
3054 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3055 return l1->getFamilyField();
3058 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3060 if(meshDimRelToMaxExt==1)
3062 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3063 return l1->getFamilyField();
3067 * Returns the optional numbers of mesh entities of a given dimension.
3068 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3069 * \return const DataArrayInt * - the array of the entity numbers.
3070 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3072 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3074 if(meshDimRelToMaxExt==1)
3076 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3077 return l1->getNumberField();
3080 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3082 if(meshDimRelToMaxExt==1)
3083 return _name_coords;
3084 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3085 return l1->getNameField();
3089 * 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).
3091 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3092 * \param [in] gt - The input geometric type for which the part definition is requested.
3093 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3095 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3097 if(meshDimRelToMaxExt==1)
3098 return _part_coords;
3099 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3100 return l1->getPartDef(gt);
3103 int MEDFileUMesh::getNumberOfNodes() const
3105 const DataArrayDouble *coo(_coords);
3107 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3108 return coo->getNumberOfTuples();
3111 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3113 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3114 return l1->getNumberOfCells();
3117 bool MEDFileUMesh::hasImplicitPart() const
3122 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3124 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3127 void MEDFileUMesh::releaseImplicitPartIfAny() const
3131 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3133 std::size_t sz(st.getNumberOfItems());
3134 for(std::size_t i=0;i<sz;i++)
3136 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3137 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3138 if(st[i].getPflName().empty())
3139 m->computeNodeIdsAlg(nodesFetched);
3142 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3143 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3144 m2->computeNodeIdsAlg(nodesFetched);
3149 MEDFileMesh *MEDFileUMesh::cartesianize() const
3151 if(getAxType()==AX_CART)
3154 return const_cast<MEDFileUMesh *>(this);
3158 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3159 const DataArrayDouble *coords(_coords);
3161 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3162 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsCart(_coords->cartesianize(getAxType()));
3163 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3164 if((const MEDFileUMeshSplitL1 *)(*it))
3165 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3166 ret->_coords=coordsCart;
3167 ret->setAxType(AX_CART);
3173 * Returns the optional numbers of mesh entities of a given dimension transformed using
3174 * DataArrayInt::invertArrayN2O2O2N().
3175 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3176 * \return const DataArrayInt * - the array of the entity numbers transformed using
3177 * DataArrayInt::invertArrayN2O2O2N().
3178 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3180 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3182 if(meshDimRelToMaxExt==1)
3184 if(!((const DataArrayInt *)_num_coords))
3185 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3186 return _rev_num_coords;
3188 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3189 return l1->getRevNumberField();
3193 * Returns a pointer to the node coordinates array of \a this mesh \b without
3194 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3196 DataArrayDouble *MEDFileUMesh::getCoords() const
3198 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
3199 if((DataArrayDouble *)tmp)
3207 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3208 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3210 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3211 * \param [in] grp - the name of the group whose mesh entities are included in the
3213 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3214 * according to the optional numbers of entities, if available.
3215 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3216 * delete this mesh using decrRef() as it is no more needed.
3217 * \throw If the name of a nonexistent group is specified.
3218 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3220 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3222 synchronizeTinyInfoOnLeaves();
3223 std::vector<std::string> tmp(1);
3225 return getGroups(meshDimRelToMaxExt,tmp,renum);
3229 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3230 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3232 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3233 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3235 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3236 * according to the optional numbers of entities, if available.
3237 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3238 * delete this mesh using decrRef() as it is no more needed.
3239 * \throw If a name of a nonexistent group is present in \a grps.
3240 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3242 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3244 synchronizeTinyInfoOnLeaves();
3245 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3246 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3247 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3248 zeRet->setName(grps[0]);
3249 return zeRet.retn();
3253 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3254 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3256 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3257 * \param [in] fam - the name of the family whose mesh entities are included in the
3259 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3260 * according to the optional numbers of entities, if available.
3261 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3262 * delete this mesh using decrRef() as it is no more needed.
3263 * \throw If a name of a nonexistent family is present in \a grps.
3264 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3266 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3268 synchronizeTinyInfoOnLeaves();
3269 std::vector<std::string> tmp(1);
3271 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3275 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3276 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3278 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3279 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3281 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3282 * according to the optional numbers of entities, if available.
3283 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3284 * delete this mesh using decrRef() as it is no more needed.
3285 * \throw If a name of a nonexistent family is present in \a fams.
3286 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3288 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3290 synchronizeTinyInfoOnLeaves();
3291 if(meshDimRelToMaxExt==1)
3293 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3294 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3295 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3299 std::vector<int> famIds=getFamiliesIds(fams);
3300 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3301 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3303 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3305 zeRet=l1->getFamilyPart(0,0,renum);
3306 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3307 zeRet->setName(fams[0]);
3308 return zeRet.retn();
3312 * Returns ids of mesh entities contained in given families of a given dimension.
3313 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3315 * \param [in] fams - the names of the families of interest.
3316 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3317 * returned instead of ids.
3318 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3319 * numbers, if available and required, of mesh entities of the families. The caller
3320 * is to delete this array using decrRef() as it is no more needed.
3321 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3323 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3325 std::vector<int> famIds=getFamiliesIds(fams);
3326 if(meshDimRelToMaxExt==1)
3328 if((const DataArrayInt *)_fam_coords)
3330 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3332 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3334 da=_fam_coords->getIdsEqualList(0,0);
3336 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3341 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3343 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3345 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3347 return l1->getFamilyPartArr(0,0,renum);
3351 * Returns a MEDCouplingUMesh of a given relative dimension.
3352 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3353 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3354 * To build a valid MEDCouplingUMesh from the returned one in this case,
3355 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3356 * \param [in] meshDimRelToMax - the relative dimension of interest.
3357 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3358 * optional numbers of mesh entities.
3359 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3360 * delete using decrRef() as it is no more needed.
3361 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3362 * \sa getGenMeshAtLevel()
3364 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3366 synchronizeTinyInfoOnLeaves();
3367 if(meshDimRelToMaxExt==1)
3371 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3372 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3373 umesh->setCoords(cc);
3374 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3375 umesh->setName(getName());
3379 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3380 return l1->getWholeMesh(renum);
3384 * Returns a MEDCouplingUMesh of a given relative dimension.
3385 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3386 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3387 * To build a valid MEDCouplingUMesh from the returned one in this case,
3388 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3389 * \param [in] meshDimRelToMax - the relative dimension of interest.
3390 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3391 * optional numbers of mesh entities.
3392 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3393 * delete using decrRef() as it is no more needed.
3394 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3395 * \sa getMeshAtLevel()
3397 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3399 return getMeshAtLevel(meshDimRelToMax,renum);
3402 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3404 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3405 return l1->getDistributionOfTypes();
3409 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3410 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3411 * optional numbers of mesh entities.
3412 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3413 * delete using decrRef() as it is no more needed.
3414 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3416 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3418 return getMeshAtLevel(0,renum);
3422 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3423 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3424 * optional numbers of mesh entities.
3425 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3426 * delete using decrRef() as it is no more needed.
3427 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3429 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3431 return getMeshAtLevel(-1,renum);
3435 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3436 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3437 * optional numbers of mesh entities.
3438 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3439 * delete using decrRef() as it is no more needed.
3440 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3442 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3444 return getMeshAtLevel(-2,renum);
3448 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3449 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3450 * optional numbers of mesh entities.
3451 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3452 * delete using decrRef() as it is no more needed.
3453 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3455 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3457 return getMeshAtLevel(-3,renum);
3461 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3462 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3463 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3464 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3466 void MEDFileUMesh::forceComputationOfParts() const
3468 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3470 const MEDFileUMeshSplitL1 *elt(*it);
3472 elt->forceComputationOfParts();
3477 * This method returns a vector of mesh parts containing each exactly one geometric type.
3478 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3479 * This method is only for memory aware users.
3480 * The returned pointers are **NOT** new object pointer. No need to mange them.
3482 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3484 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3485 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3489 * This method returns the part of \a this having the geometric type \a gt.
3490 * If such part is not existing an exception will be thrown.
3491 * The returned pointer is **NOT** new object pointer. No need to mange it.
3493 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3495 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3496 int lev=(int)cm.getDimension()-getMeshDimension();
3497 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3498 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3502 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3503 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3505 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3507 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3508 return sp->getGeoTypes();
3511 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3513 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3514 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3515 return sp->getNumberOfCellsWithType(ct);
3519 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3520 * \param [in] gt - the geometric type for which the family field is asked.
3521 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3522 * delete using decrRef() as it is no more needed.
3523 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3525 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3527 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3528 int lev=(int)cm.getDimension()-getMeshDimension();
3529 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3530 return sp->extractFamilyFieldOnGeoType(gt);
3534 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3535 * \param [in] gt - the geometric type for which the number field is asked.
3536 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3537 * delete using decrRef() as it is no more needed.
3538 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3540 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3542 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3543 int lev=(int)cm.getDimension()-getMeshDimension();
3544 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3545 return sp->extractNumberFieldOnGeoType(gt);
3549 * This method returns for specified geometric type \a gt the relative level to \a this.
3550 * If the relative level is empty an exception will be thrown.
3552 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3554 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3555 int ret((int)cm.getDimension()-getMeshDimension());
3556 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3560 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3562 if(meshDimRelToMaxExt==1)
3563 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3564 if(meshDimRelToMaxExt>1)
3565 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3566 int tracucedRk=-meshDimRelToMaxExt;
3567 if(tracucedRk>=(int)_ms.size())
3568 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3569 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3570 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3571 return _ms[tracucedRk];
3574 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3576 if(meshDimRelToMaxExt==1)
3577 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3578 if(meshDimRelToMaxExt>1)
3579 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3580 int tracucedRk=-meshDimRelToMaxExt;
3581 if(tracucedRk>=(int)_ms.size())
3582 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3583 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3584 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3585 return _ms[tracucedRk];
3588 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3590 if(-meshDimRelToMax>=(int)_ms.size())
3591 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3593 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3595 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3597 int ref=(*it)->getMeshDimension();
3598 if(ref+i!=meshDim-meshDimRelToMax)
3599 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3605 * Sets the node coordinates array of \a this mesh.
3606 * \param [in] coords - the new node coordinates array.
3607 * \throw If \a coords == \c NULL.
3609 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3612 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3613 if(coords==(DataArrayDouble *)_coords)
3615 coords->checkAllocated();
3616 int nbOfTuples=coords->getNumberOfTuples();
3619 _fam_coords=DataArrayInt::New();
3620 _fam_coords->alloc(nbOfTuples,1);
3621 _fam_coords->fillWithZero();
3622 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3623 if((MEDFileUMeshSplitL1 *)(*it))
3624 (*it)->setCoords(coords);
3628 * Removes all groups of a given dimension in \a this mesh.
3629 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3630 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3632 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3634 if(meshDimRelToMaxExt==1)
3636 if((DataArrayInt *)_fam_coords)
3637 _fam_coords->fillWithZero();
3640 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3641 l1->eraseFamilyField();
3646 * Removes all families with ids not present in the family fields of \a this mesh.
3648 void MEDFileUMesh::optimizeFamilies()
3650 std::vector<int> levs=getNonEmptyLevelsExt();
3651 std::set<int> allFamsIds;
3652 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3654 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3655 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3657 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3660 std::set<std::string> famNamesToKill;
3661 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3663 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3664 famNamesToKill.insert((*it).first);
3666 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3667 _families.erase(*it);
3668 std::vector<std::string> grpNamesToKill;
3669 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3671 std::vector<std::string> tmp;
3672 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3674 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3675 tmp.push_back(*it2);
3680 tmp.push_back((*it).first);
3682 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3687 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3688 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3689 * The boundary is built according to the following method:
3690 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3691 * coordinates array is extended).
3692 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated.
3693 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3694 * other side of the group is no more a neighbor)
3695 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3696 * bordering the newly created boundary use the newly computed nodes.
3698 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3699 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3701 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3702 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3704 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3705 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3707 std::vector<int> levs=getNonEmptyLevels();
3708 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3709 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3710 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3711 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3712 int nbNodes=m0->getNumberOfNodes();
3713 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3714 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3715 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3716 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3717 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3718 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3719 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3720 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3721 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3722 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3723 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3724 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3725 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3726 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3727 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3728 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3729 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3730 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3731 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3732 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3733 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3734 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3735 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3736 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3737 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3738 m0->setCoords(tmp0->getCoords());
3739 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3740 m1->setCoords(m0->getCoords());
3741 _coords=m0->getCoords(); _coords->incrRef();
3742 // duplication of cells in group 'grpNameM1' on level -1
3743 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3744 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3745 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3746 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3747 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3749 newm1->setName(getName());
3750 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3752 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !");
3753 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3754 newFam->alloc(newm1->getNumberOfCells(),1);
3755 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3756 // Positive ID for family of nodes, negative for all the rest.
3758 if (m1->getMeshDimension() == 0)
3759 idd=getMaxFamilyId()+1;
3761 idd=getMinFamilyId()-1;
3762 int globStart=0,start=0,end,globEnd;
3763 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3764 for(int i=0;i<nbOfChunks;i++)
3766 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3767 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3769 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3770 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3771 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3776 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3780 newm1->setCoords(getCoords());
3781 setMeshAtLevel(-1,newm1);
3782 setFamilyFieldArr(-1,newFam);
3783 std::string grpName2(grpNameM1); grpName2+="_dup";
3784 addFamily(grpName2,idd);
3785 addFamilyOnGrp(grpName2,grpName2);
3790 int newNbOfNodes=getCoords()->getNumberOfTuples();
3791 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3792 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3793 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3796 nodesDuplicated=nodeIdsToDuplicate.retn();
3797 cellsModified=cellsToModifyConn0.retn();
3798 cellsNotModified=cellsToModifyConn1.retn();
3802 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3803 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3804 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3806 * \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.
3807 * 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.
3809 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3811 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3812 std::vector<int> levs=getNonEmptyLevels();
3814 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3815 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3818 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3820 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3821 std::vector<int> code1=m->getDistributionOfTypes();
3822 end=PutInThirdComponentOfCodeOffset(code1,start);
3823 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3824 bool hasChanged=m->unPolyze();
3825 DataArrayInt *fake=0;
3826 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3827 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3829 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3832 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3833 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3835 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3836 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3837 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3838 setMeshAtLevel(*it,m);
3839 std::vector<int> code2=m->getDistributionOfTypes();
3840 end=PutInThirdComponentOfCodeOffset(code2,start);
3841 newCode.insert(newCode.end(),code2.begin(),code2.end());
3843 if(o2nCellsPart2->isIdentity())
3847 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3848 setFamilyFieldArr(*it,newFamField);
3852 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3853 setRenumFieldArr(*it,newNumField);
3858 newCode.insert(newCode.end(),code1.begin(),code1.end());
3864 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3865 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3866 o2nRenumCell=o2nRenumCellRet.retn();
3871 /*! \cond HIDDEN_ITEMS */
3872 struct MEDLoaderAccVisit1
3874 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3875 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3876 int _new_nb_of_nodes;
3881 * 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.
3882 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3883 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3884 * -1 values in returned array means that the corresponding old node is no more used.
3886 * \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
3887 * is modified in \a this.
3888 * \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
3891 DataArrayInt *MEDFileUMesh::zipCoords()
3893 const DataArrayDouble *coo(getCoords());
3895 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3896 int nbOfNodes(coo->getNumberOfTuples());
3897 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3898 std::vector<int> neLevs(getNonEmptyLevels());
3899 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3901 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3902 if(zeLev->isMeshStoredSplitByType())
3904 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3905 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3907 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3911 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3912 mesh->computeNodeIdsAlg(nodeIdsInUse);
3915 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3916 if(nbrOfNodesInUse==nbOfNodes)
3917 return 0;//no need to update _part_coords
3918 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3919 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3920 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3921 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3922 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3923 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3924 if((const DataArrayInt *)_fam_coords)
3925 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3926 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3927 if((const DataArrayInt *)_num_coords)
3928 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3929 if((const DataArrayAsciiChar *)_name_coords)
3930 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3931 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3932 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3934 if((MEDFileUMeshSplitL1*)*it)
3936 (*it)->renumberNodesInConn(ret->begin());
3937 (*it)->setCoords(_coords);
3940 // updates _part_coords
3941 const PartDefinition *pc(_part_coords);
3944 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3945 _part_coords=tmpPD->composeWith(pc);
3951 * This method performs an extrusion along a path defined by \a m1D.
3952 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3953 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3954 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3955 * This method scans all levels in \a this
3956 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3958 * \param [in] m1D - the mesh defining the extrusion path.
3959 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3960 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3962 * \sa MEDCouplingUMesh::buildExtrudedMesh
3964 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3966 if(getMeshDimension()!=2)
3967 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3968 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3969 m1D->checkCoherency();
3970 if(m1D->getMeshDimension()!=1)
3971 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3972 int nbRep(m1D->getNumberOfCells());
3973 std::vector<int> levs(getNonEmptyLevels());
3974 std::vector<std::string> grps(getGroupsNames());
3975 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3976 DataArrayDouble *coords(0);
3977 std::size_t nbOfLevsOut(levs.size()+1);
3978 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3979 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3981 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3982 item=item->clone(false);
3983 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3984 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3985 tmp->changeSpaceDimension(3+(*lev),0.);
3986 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3987 zeList.push_back(elt);
3989 coords=elt->getCoords();
3992 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3993 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3995 (*it)->setName(getName());
3996 (*it)->setCoords(coords);
3998 for(std::size_t ii=0;ii!=zeList.size();ii++)
4001 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
4004 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4005 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
4006 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
4007 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4008 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4009 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4010 std::vector<const MEDCouplingUMesh *> elts(3);
4011 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4012 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4013 elt->setName(getName());
4016 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4017 ret->setMeshAtLevel(lev,elt);
4019 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4020 endLev=endLev->clone(false); endLev->setCoords(coords);
4021 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
4022 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4023 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4024 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4025 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4026 endLev->setName(getName());
4027 ret->setMeshAtLevel(levs.back()-1,endLev);
4029 for(std::size_t ii=0;ii!=zeList.size();ii++)
4032 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
4033 std::vector< const DataArrayInt * > outGrps2;
4036 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4038 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4039 if(!grpArr->empty())
4041 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
4042 int offset0(zeList[ii]->getNumberOfCells());
4043 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4044 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4045 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4046 grpArr2->setName(oss.str());
4047 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4048 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4049 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4050 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4055 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4057 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4058 if(!grpArr->empty())
4060 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4061 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
4062 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4063 for(int iii=0;iii<nbRep;iii++)
4065 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4066 grpArrs2[iii]=grpArrs[iii];
4068 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4069 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4070 std::ostringstream grpName; grpName << *grp << "_extruded";
4071 grpArrExt->setName(grpName.str());
4072 outGrps.push_back(grpArrExt);
4073 outGrps2.push_back(grpArrExt);
4076 ret->setGroupsAtLevel(lev,outGrps2);
4078 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
4079 std::vector< const DataArrayInt * > outGrps2;
4080 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4082 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4083 if(grpArr1->empty())
4085 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
4086 std::ostringstream grpName; grpName << *grp << "_top";
4087 grpArr2->setName(grpName.str());
4088 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4089 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4090 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4092 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4097 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4098 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4099 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4101 * \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
4102 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4103 * \param [in] eps - detection threshold for coordinates.
4104 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4106 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4108 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4110 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4111 int initialNbNodes(getNumberOfNodes());
4112 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4113 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4115 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4117 DataArrayDouble *zeCoords(m0->getCoords());
4118 ret->setMeshAtLevel(0,m0);
4119 std::vector<int> levs(getNonEmptyLevels());
4120 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4123 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4124 ret->setFamilyFieldArr(0,famFieldCpy);
4126 famField=getFamilyFieldAtLevel(1);
4129 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4130 fam->fillWithZero();
4131 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4132 ret->setFamilyFieldArr(1,fam);
4134 ret->copyFamGrpMapsFrom(*this);
4135 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4136 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4140 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4141 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4142 if(m1->getMeshDimension()!=0)
4145 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4146 }//kill unused notUsed var
4147 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
4149 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4150 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4153 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4154 throw INTERP_KERNEL::Exception(oss.str().c_str());
4156 b->applyLin(1,initialNbNodes);
4157 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4158 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4159 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4160 m1->renumberNodesInConn(renum->begin());
4162 m1->setCoords(zeCoords);
4163 ret->setMeshAtLevel(*lev,m1);
4164 famField=getFamilyFieldAtLevel(*lev);
4167 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4168 ret->setFamilyFieldArr(*lev,famFieldCpy);
4175 * This method converts all quadratic cells in \a this into linear cells.
4176 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4177 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4179 * \param [in] eps - detection threshold for coordinates.
4180 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4182 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4184 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4186 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4187 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4188 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4189 m0->convertQuadraticCellsToLinear();
4191 DataArrayDouble *zeCoords(m0->getCoords());
4192 ret->setMeshAtLevel(0,m0);
4193 std::vector<int> levs(getNonEmptyLevels());
4194 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4197 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4198 ret->setFamilyFieldArr(0,famFieldCpy);
4200 famField=getFamilyFieldAtLevel(1);
4203 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
4204 ret->setFamilyFieldArr(1,fam);
4206 ret->copyFamGrpMapsFrom(*this);
4207 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4211 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4212 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4213 m1->convertQuadraticCellsToLinear();
4216 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4217 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4220 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4221 throw INTERP_KERNEL::Exception(oss.str().c_str());
4223 m1->renumberNodesInConn(b->begin());
4224 m1->setCoords(zeCoords);
4225 ret->setMeshAtLevel(*lev,m1);
4226 famField=getFamilyFieldAtLevel(*lev);
4229 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4230 ret->setFamilyFieldArr(*lev,famFieldCpy);
4236 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4238 clearNonDiscrAttributes();
4239 forceComputationOfParts();
4240 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4241 std::vector<int> layer0;
4242 layer0.push_back(getAxType());//0 i
4243 layer0.push_back(_order); //1 i
4244 layer0.push_back(_iteration);//2 i
4245 layer0.push_back(getSpaceDimension());//3 i
4246 tinyDouble.push_back(_time);//0 d
4247 tinyStr.push_back(_name);//0 s
4248 tinyStr.push_back(_desc_name);//1 s
4249 for(int i=0;i<getSpaceDimension();i++)
4250 tinyStr.push_back(_coords->getInfoOnComponent(i));
4251 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4252 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4254 tinyStr.push_back((*it).first);
4255 layer0.push_back((*it).second);
4257 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4258 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4260 layer0.push_back((int)(*it0).second.size());
4261 tinyStr.push_back((*it0).first);
4262 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4263 tinyStr.push_back(*it1);
4265 // sizeof(layer0)==4+aa+1+bb layer#0
4266 bigArrayD=_coords;// 0 bd
4267 bigArraysI.push_back(_fam_coords);// 0 bi
4268 bigArraysI.push_back(_num_coords);// 1 bi
4269 const PartDefinition *pd(_part_coords);
4271 layer0.push_back(-1);
4274 std::vector<int> tmp0;
4275 pd->serialize(tmp0,bigArraysI);
4276 tinyInt.push_back(tmp0.size());
4277 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4280 std::vector<int> layer1;
4281 std::vector<int> levs(getNonEmptyLevels());
4282 layer1.push_back((int)levs.size());// 0 i <- key
4283 layer1.insert(layer1.end(),levs.begin(),levs.end());
4284 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4286 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4287 lev->serialize(layer1,bigArraysI);
4289 // put layers all together.
4290 tinyInt.push_back(layer0.size());
4291 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4292 tinyInt.push_back(layer1.size());
4293 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4296 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4297 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4299 int sz0(tinyInt[0]);
4300 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4301 int sz1(tinyInt[sz0+1]);
4302 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4304 std::reverse(layer0.begin(),layer0.end());
4305 std::reverse(layer1.begin(),layer1.end());
4306 std::reverse(tinyDouble.begin(),tinyDouble.end());
4307 std::reverse(tinyStr.begin(),tinyStr.end());
4308 std::reverse(bigArraysI.begin(),bigArraysI.end());
4310 setAxType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4311 _order=layer0.back(); layer0.pop_back();
4312 _iteration=layer0.back(); layer0.pop_back();
4313 int spaceDim(layer0.back()); layer0.pop_back();
4314 _time=tinyDouble.back(); tinyDouble.pop_back();
4315 _name=tinyStr.back(); tinyStr.pop_back();
4316 _desc_name=tinyStr.back(); tinyStr.pop_back();
4317 _coords=bigArrayD; _coords->rearrange(spaceDim);
4318 for(int i=0;i<spaceDim;i++)
4320 _coords->setInfoOnComponent(i,tinyStr.back());
4323 int nbOfFams(layer0.back()); layer0.pop_back();
4325 for(int i=0;i<nbOfFams;i++)
4327 _families[tinyStr.back()]=layer0.back();
4328 tinyStr.pop_back(); layer0.pop_back();
4330 int nbGroups(layer0.back()); layer0.pop_back();
4332 for(int i=0;i<nbGroups;i++)
4334 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4335 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4336 std::vector<std::string> fams(nbOfFamsOnGrp);
4337 for(int j=0;j<nbOfFamsOnGrp;j++)
4339 fams[j]=tinyStr.back(); tinyStr.pop_back();
4341 _groups[grpName]=fams;
4343 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4344 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4346 int isPd(layer0.back()); layer0.pop_back();
4349 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4350 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4351 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4354 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4356 int nbLevs(layer1.back()); layer1.pop_back();
4357 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4359 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4360 _ms.resize(maxLev+1);
4361 for(int i=0;i<nbLevs;i++)
4365 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4370 * Adds a group of nodes to \a this mesh.
4371 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4372 * The ids should be sorted and different each other (MED file norm).
4374 * \warning this method can alter default "FAMILLE_ZERO" family.
4375 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4377 * \throw If the node coordinates array is not set.
4378 * \throw If \a ids == \c NULL.
4379 * \throw If \a ids->getName() == "".
4380 * \throw If \a ids does not respect the MED file norm.
4381 * \throw If a group with name \a ids->getName() already exists.
4383 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4385 const DataArrayDouble *coords(_coords);
4387 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4388 int nbOfNodes(coords->getNumberOfTuples());
4389 if(!((DataArrayInt *)_fam_coords))
4390 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4392 addGroupUnderground(true,ids,_fam_coords);
4396 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4398 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4399 * The ids should be sorted and different each other (MED file norm).
4401 * \warning this method can alter default "FAMILLE_ZERO" family.
4402 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4404 * \throw If the node coordinates array is not set.
4405 * \throw If \a ids == \c NULL.
4406 * \throw If \a ids->getName() == "".
4407 * \throw If \a ids does not respect the MED file norm.
4408 * \throw If a group with name \a ids->getName() already exists.
4410 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4412 std::vector<int> levs(getNonEmptyLevelsExt());
4413 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4415 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4416 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4418 if(meshDimRelToMaxExt==1)
4419 { addNodeGroup(ids); return ; }
4420 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4421 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4422 addGroupUnderground(false,ids,fam);
4426 * Changes a name of a family specified by its id.
4427 * \param [in] id - the id of the family of interest.
4428 * \param [in] newFamName - the new family name.
4429 * \throw If no family with the given \a id exists.
4431 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4433 std::string oldName=getFamilyNameGivenId(id);
4434 _families.erase(oldName);
4435 _families[newFamName]=id;
4439 * Removes a mesh of a given dimension.
4440 * \param [in] meshDimRelToMax - the relative dimension of interest.
4441 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4443 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4445 std::vector<int> levSet=getNonEmptyLevels();
4446 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4447 if(it==levSet.end())
4448 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4449 int pos=(-meshDimRelToMax);
4454 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4455 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4456 * \param [in] m - the new mesh to set.
4457 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4459 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4460 * another node coordinates array.
4461 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4462 * to the existing meshes of other levels of \a this mesh.
4464 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4466 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4467 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4471 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4472 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4473 * \param [in] m - the new mesh to set.
4474 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4475 * writing \a this mesh in a MED file.
4476 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4478 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4479 * another node coordinates array.
4480 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4481 * to the existing meshes of other levels of \a this mesh.
4483 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4485 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4486 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4489 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4491 dealWithTinyInfo(m);
4492 std::vector<int> levSet=getNonEmptyLevels();
4493 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4495 if((DataArrayDouble *)_coords==0)
4497 DataArrayDouble *c=m->getCoords();
4502 if(m->getCoords()!=_coords)
4503 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4504 int sz=(-meshDimRelToMax)+1;
4505 if(sz>=(int)_ms.size())
4507 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4511 return _ms[-meshDimRelToMax];
4515 * This method allows to set at once the content of different levels in \a this.
4516 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4518 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4519 * \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.
4520 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4522 * \throw If \a there is a null pointer in \a ms.
4523 * \sa MEDFileUMesh::setMeshAtLevel
4525 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4529 const MEDCouplingUMesh *mRef=ms[0];
4531 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4532 std::string name(mRef->getName());
4533 const DataArrayDouble *coo(mRef->getCoords());
4536 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4538 const MEDCouplingUMesh *cur(*it);
4540 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4541 if(coo!=cur->getCoords())
4542 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4543 int mdim=cur->getMeshDimension();
4544 zeDim=std::max(zeDim,mdim);
4545 if(s.find(mdim)!=s.end())
4546 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4548 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4550 int mdim=(*it)->getMeshDimension();
4551 setName((*it)->getName());
4552 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4558 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4559 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4560 * The given meshes must share the same node coordinates array.
4561 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4562 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4563 * create in \a this mesh.
4564 * \throw If \a ms is empty.
4565 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4566 * to the existing meshes of other levels of \a this mesh.
4567 * \throw If the meshes in \a ms do not share the same node coordinates array.
4568 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4569 * of the given meshes.
4570 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4571 * \throw If names of some meshes in \a ms are equal.
4572 * \throw If \a ms includes a mesh with an empty name.
4574 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4577 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4578 int sz=(-meshDimRelToMax)+1;
4579 if(sz>=(int)_ms.size())
4581 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4582 DataArrayDouble *coo=checkMultiMesh(ms);
4583 if((DataArrayDouble *)_coords==0)
4589 if((DataArrayDouble *)_coords!=coo)
4590 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4591 std::vector<DataArrayInt *> corr;
4592 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4593 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4594 setMeshAtLevel(meshDimRelToMax,m,renum);
4595 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4596 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4600 * Creates groups at a given level in \a this mesh from a sequence of
4601 * meshes each representing a group.
4602 * The given meshes must share the same node coordinates array.
4603 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4604 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4605 * create in \a this mesh.
4606 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4608 * \throw If \a ms is empty.
4609 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4610 * to the existing meshes of other levels of \a this mesh.
4611 * \throw If the meshes in \a ms do not share the same node coordinates array.
4612 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4613 * of the given meshes.
4614 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4615 * \throw If names of some meshes in \a ms are equal.
4616 * \throw If \a ms includes a mesh with an empty name.
4618 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4621 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4622 int sz=(-meshDimRelToMax)+1;
4623 if(sz>=(int)_ms.size())
4625 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4626 DataArrayDouble *coo=checkMultiMesh(ms);
4627 if((DataArrayDouble *)_coords==0)
4633 if((DataArrayDouble *)_coords!=coo)
4634 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4635 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4636 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4638 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4640 DataArrayInt *arr=0;
4641 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4645 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4646 throw INTERP_KERNEL::Exception(oss.str().c_str());
4649 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4650 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4653 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4655 const DataArrayDouble *ret=ms[0]->getCoords();
4656 int mdim=ms[0]->getMeshDimension();
4657 for(unsigned int i=1;i<ms.size();i++)
4659 ms[i]->checkCoherency();
4660 if(ms[i]->getCoords()!=ret)
4661 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4662 if(ms[i]->getMeshDimension()!=mdim)
4663 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4665 return const_cast<DataArrayDouble *>(ret);
4669 * Sets the family field of a given relative dimension.
4670 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4671 * the family field is set.
4672 * \param [in] famArr - the array of the family field.
4673 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4674 * \throw If \a famArr has an invalid size.
4676 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4678 if(meshDimRelToMaxExt==1)
4685 DataArrayDouble *coo(_coords);
4687 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4688 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4693 if(meshDimRelToMaxExt>1)
4694 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4695 int traducedRk=-meshDimRelToMaxExt;
4696 if(traducedRk>=(int)_ms.size())
4697 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4698 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4699 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4700 return _ms[traducedRk]->setFamilyArr(famArr);
4704 * Sets the optional numbers of mesh entities of a given dimension.
4705 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4706 * \param [in] renumArr - the array of the numbers.
4707 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4708 * \throw If \a renumArr has an invalid size.
4710 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4712 if(meshDimRelToMaxExt==1)
4720 DataArrayDouble *coo(_coords);
4722 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4723 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4724 renumArr->incrRef();
4725 _num_coords=renumArr;
4729 if(meshDimRelToMaxExt>1)
4730 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4731 int traducedRk=-meshDimRelToMaxExt;
4732 if(traducedRk>=(int)_ms.size())
4733 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4734 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4735 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4736 return _ms[traducedRk]->setRenumArr(renumArr);
4740 * Sets the optional names of mesh entities of a given dimension.
4741 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4742 * \param [in] nameArr - the array of the names.
4743 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4744 * \throw If \a nameArr has an invalid size.
4746 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4748 if(meshDimRelToMaxExt==1)
4755 DataArrayDouble *coo(_coords);
4757 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4758 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4760 _name_coords=nameArr;
4763 if(meshDimRelToMaxExt>1)
4764 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4765 int traducedRk=-meshDimRelToMaxExt;
4766 if(traducedRk>=(int)_ms.size())
4767 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4768 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4769 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4770 return _ms[traducedRk]->setNameArr(nameArr);
4773 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4775 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4776 if((const MEDFileUMeshSplitL1 *)(*it))
4777 (*it)->synchronizeTinyInfo(*this);
4781 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4783 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4785 DataArrayInt *arr=_fam_coords;
4787 arr->changeValue(oldId,newId);
4788 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4790 MEDFileUMeshSplitL1 *sp=(*it);
4793 sp->changeFamilyIdArr(oldId,newId);
4798 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4800 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4801 const DataArrayInt *da(_fam_coords);
4803 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4804 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4806 const MEDFileUMeshSplitL1 *elt(*it);
4809 da=elt->getFamilyField();
4811 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4817 void MEDFileUMesh::computeRevNum() const
4819 if((const DataArrayInt *)_num_coords)
4822 int maxValue=_num_coords->getMaxValue(pos);
4823 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4827 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4829 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4832 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4834 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4835 ret.push_back((const DataArrayInt *)_fam_nodes);
4836 ret.push_back((const DataArrayInt *)_num_nodes);
4837 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4838 ret.push_back((const DataArrayInt *)_fam_cells);
4839 ret.push_back((const DataArrayInt *)_num_cells);
4840 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4841 ret.push_back((const DataArrayInt *)_fam_faces);
4842 ret.push_back((const DataArrayInt *)_num_faces);
4843 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4844 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4845 ret.push_back((const DataArrayInt *)_rev_num_cells);
4846 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4850 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4852 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4853 if((const DataArrayInt *)_fam_nodes)
4855 int val=_fam_nodes->getMaxValue(tmp);
4856 ret=std::max(ret,std::abs(val));
4858 if((const DataArrayInt *)_fam_cells)
4860 int val=_fam_cells->getMaxValue(tmp);
4861 ret=std::max(ret,std::abs(val));
4863 if((const DataArrayInt *)_fam_faces)
4865 int val=_fam_faces->getMaxValue(tmp);
4866 ret=std::max(ret,std::abs(val));
4871 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4873 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4874 if((const DataArrayInt *)_fam_nodes)
4876 int val=_fam_nodes->getMaxValue(tmp);
4877 ret=std::max(ret,val);
4879 if((const DataArrayInt *)_fam_cells)
4881 int val=_fam_cells->getMaxValue(tmp);
4882 ret=std::max(ret,val);
4884 if((const DataArrayInt *)_fam_faces)
4886 int val=_fam_faces->getMaxValue(tmp);
4887 ret=std::max(ret,val);
4892 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4894 int ret=std::numeric_limits<int>::max(),tmp=-1;
4895 if((const DataArrayInt *)_fam_nodes)
4897 int val=_fam_nodes->getMinValue(tmp);
4898 ret=std::min(ret,val);
4900 if((const DataArrayInt *)_fam_cells)
4902 int val=_fam_cells->getMinValue(tmp);
4903 ret=std::min(ret,val);
4905 if((const DataArrayInt *)_fam_faces)
4907 int val=_fam_faces->getMinValue(tmp);
4908 ret=std::min(ret,val);
4913 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4915 if(!MEDFileMesh::isEqual(other,eps,what))
4917 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4920 what="Mesh types differ ! This is structured and other is NOT !";
4923 const DataArrayInt *famc1=_fam_nodes;
4924 const DataArrayInt *famc2=otherC->_fam_nodes;
4925 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4927 what="Mismatch of families arr on nodes ! One is defined and not other !";
4932 bool ret=famc1->isEqual(*famc2);
4935 what="Families arr on nodes differ !";
4940 famc2=otherC->_fam_cells;
4941 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4943 what="Mismatch of families arr on cells ! One is defined and not other !";
4948 bool ret=famc1->isEqual(*famc2);
4951 what="Families arr on cells differ !";
4956 famc2=otherC->_fam_faces;
4957 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4959 what="Mismatch of families arr on faces ! One is defined and not other !";
4964 bool ret=famc1->isEqual(*famc2);
4967 what="Families arr on faces differ !";
4972 famc2=otherC->_num_nodes;
4973 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4975 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4980 bool ret=famc1->isEqual(*famc2);
4983 what="Numbering arr on nodes differ !";
4988 famc2=otherC->_num_cells;
4989 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4991 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4996 bool ret=famc1->isEqual(*famc2);
4999 what="Numbering arr on cells differ !";
5004 famc2=otherC->_num_faces;
5005 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5007 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5012 bool ret=famc1->isEqual(*famc2);
5015 what="Numbering arr on faces differ !";
5019 const DataArrayAsciiChar *d1=_names_cells;
5020 const DataArrayAsciiChar *d2=otherC->_names_cells;
5021 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5023 what="Mismatch of naming arr on cells ! One is defined and not other !";
5028 bool ret=d1->isEqual(*d2);
5031 what="Naming arr on cells differ !";
5036 d2=otherC->_names_faces;
5037 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5039 what="Mismatch of naming arr on faces ! One is defined and not other !";
5044 bool ret=d1->isEqual(*d2);
5047 what="Naming arr on faces differ !";
5052 d2=otherC->_names_nodes;
5053 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5055 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5060 bool ret=d1->isEqual(*d2);
5063 what="Naming arr on nodes differ !";
5070 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5072 MEDFileMesh::clearNonDiscrAttributes();
5073 const DataArrayInt *tmp=_fam_nodes;
5075 (const_cast<DataArrayInt *>(tmp))->setName("");
5078 (const_cast<DataArrayInt *>(tmp))->setName("");
5081 (const_cast<DataArrayInt *>(tmp))->setName("");
5084 (const_cast<DataArrayInt *>(tmp))->setName("");
5087 (const_cast<DataArrayInt *>(tmp))->setName("");
5090 (const_cast<DataArrayInt *>(tmp))->setName("");
5094 * Returns ids of mesh entities contained in given families of a given dimension.
5095 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5097 * \param [in] fams - the names of the families of interest.
5098 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5099 * returned instead of ids.
5100 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5101 * numbers, if available and required, of mesh entities of the families. The caller
5102 * is to delete this array using decrRef() as it is no more needed.
5103 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5105 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5107 std::vector<int> famIds(getFamiliesIds(fams));
5108 switch(meshDimRelToMaxExt)
5112 if((const DataArrayInt *)_fam_nodes)
5114 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5116 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5118 da=_fam_nodes->getIdsEqualList(0,0);
5120 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5125 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5130 if((const DataArrayInt *)_fam_cells)
5132 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5134 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5136 da=_fam_cells->getIdsEqualList(0,0);
5138 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5143 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5148 if((const DataArrayInt *)_fam_faces)
5150 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5152 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5154 da=_fam_faces->getIdsEqualList(0,0);
5156 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5161 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5165 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5167 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5171 * Sets the family field of a given relative dimension.
5172 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5173 * the family field is set.
5174 * \param [in] famArr - the array of the family field.
5175 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5176 * \throw If \a famArr has an invalid size.
5177 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5179 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5181 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5183 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5184 switch(meshDimRelToMaxExt)
5188 int nbCells=mesh->getNumberOfCells();
5189 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5195 int nbNodes=mesh->getNumberOfNodes();
5196 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5202 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5203 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5208 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5215 * Sets the optional numbers of mesh entities of a given dimension.
5216 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5217 * \param [in] renumArr - the array of the numbers.
5218 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5219 * \throw If \a renumArr has an invalid size.
5220 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5222 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5224 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5226 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5227 switch(meshDimRelToMaxExt)
5231 int nbCells=mesh->getNumberOfCells();
5232 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5233 _num_cells=renumArr;
5238 int nbNodes=mesh->getNumberOfNodes();
5239 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5240 _num_nodes=renumArr;
5245 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5246 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5247 _num_faces=renumArr;
5251 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5254 renumArr->incrRef();
5258 * Sets the optional names of mesh entities of a given dimension.
5259 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5260 * \param [in] nameArr - the array of the names.
5261 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5262 * \throw If \a nameArr has an invalid size.
5264 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5266 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5268 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5269 switch(meshDimRelToMaxExt)
5273 int nbCells=mesh->getNumberOfCells();
5274 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5275 _names_cells=nameArr;
5280 int nbNodes=mesh->getNumberOfNodes();
5281 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5282 _names_nodes=nameArr;
5287 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5288 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5289 _names_cells=nameArr;
5292 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5299 * Adds a group of nodes to \a this mesh.
5300 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5301 * The ids should be sorted and different each other (MED file norm).
5303 * \warning this method can alter default "FAMILLE_ZERO" family.
5304 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5306 * \throw If the node coordinates array is not set.
5307 * \throw If \a ids == \c NULL.
5308 * \throw If \a ids->getName() == "".
5309 * \throw If \a ids does not respect the MED file norm.
5310 * \throw If a group with name \a ids->getName() already exists.
5312 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5318 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5320 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5321 * The ids should be sorted and different each other (MED file norm).
5323 * \warning this method can alter default "FAMILLE_ZERO" family.
5324 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5326 * \throw If the node coordinates array is not set.
5327 * \throw If \a ids == \c NULL.
5328 * \throw If \a ids->getName() == "".
5329 * \throw If \a ids does not respect the MED file norm.
5330 * \throw If a group with name \a ids->getName() already exists.
5332 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5334 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5335 addGroupUnderground(false,ids,fam);
5340 * Returns the family field for mesh entities of a given dimension.
5341 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5342 * \return const DataArrayInt * - the family field. It is an array of ids of families
5343 * each mesh entity belongs to. It can be \c NULL.
5344 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5346 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5348 switch(meshDimRelToMaxExt)
5357 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5362 * Returns the family field for mesh entities of a given dimension.
5363 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5364 * \return const DataArrayInt * - the family field. It is an array of ids of families
5365 * each mesh entity belongs to. It can be \c NULL.
5366 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5368 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5370 switch(meshDimRelToMaxExt)
5379 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5384 * Returns the optional numbers of mesh entities of a given dimension.
5385 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5386 * \return const DataArrayInt * - the array of the entity numbers.
5387 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5388 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5390 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5392 switch(meshDimRelToMaxExt)
5401 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5406 * Returns the optional numbers of mesh entities of a given dimension transformed using
5407 * DataArrayInt::invertArrayN2O2O2N().
5408 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5409 * \return const DataArrayInt * - the array of the entity numbers transformed using
5410 * DataArrayInt::invertArrayN2O2O2N().
5411 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5412 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5414 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5416 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5417 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5418 if(meshDimRelToMaxExt==0)
5420 if((const DataArrayInt *)_num_cells)
5423 int maxValue=_num_cells->getMaxValue(pos);
5424 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5425 return _rev_num_cells;
5428 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5432 if((const DataArrayInt *)_num_nodes)
5435 int maxValue=_num_nodes->getMaxValue(pos);
5436 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5437 return _rev_num_nodes;
5440 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5444 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5446 switch(meshDimRelToMaxExt)
5449 return _names_cells;
5451 return _names_nodes;
5453 return _names_faces;
5455 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5460 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5461 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5463 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5465 std::vector<int> ret(1);
5470 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5471 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5473 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5475 std::vector<int> ret(2);
5481 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5483 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5485 std::vector<int> ret;
5486 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5497 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5499 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5501 std::vector<int> ret;
5502 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5513 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5515 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5517 std::vector<int> ret;
5518 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5529 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5531 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5533 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5537 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5539 DataArrayInt *arr=_fam_nodes;
5541 arr->changeValue(oldId,newId);
5544 arr->changeValue(oldId,newId);
5547 arr->changeValue(oldId,newId);
5550 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5552 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
5553 const DataArrayInt *da(_fam_nodes);
5555 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5558 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5561 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5565 void MEDFileStructuredMesh::deepCpyAttributes()
5567 if((const DataArrayInt*)_fam_nodes)
5568 _fam_nodes=_fam_nodes->deepCpy();
5569 if((const DataArrayInt*)_num_nodes)
5570 _num_nodes=_num_nodes->deepCpy();
5571 if((const DataArrayAsciiChar*)_names_nodes)
5572 _names_nodes=_names_nodes->deepCpy();
5573 if((const DataArrayInt*)_fam_cells)
5574 _fam_cells=_fam_cells->deepCpy();
5575 if((const DataArrayInt*)_num_cells)
5576 _num_cells=_num_cells->deepCpy();
5577 if((const DataArrayAsciiChar*)_names_cells)
5578 _names_cells=_names_cells->deepCpy();
5579 if((const DataArrayInt*)_fam_faces)
5580 _fam_faces=_fam_faces->deepCpy();
5581 if((const DataArrayInt*)_num_faces)
5582 _num_faces=_num_faces->deepCpy();
5583 if((const DataArrayAsciiChar*)_names_faces)
5584 _names_faces=_names_faces->deepCpy();
5585 if((const DataArrayInt*)_rev_num_nodes)
5586 _rev_num_nodes=_rev_num_nodes->deepCpy();
5587 if((const DataArrayInt*)_rev_num_cells)
5588 _rev_num_cells=_rev_num_cells->deepCpy();
5592 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5594 * \return a pointer to cartesian mesh that need to be managed by the caller.
5595 * \warning the returned pointer has to be managed by the caller.
5599 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5600 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5601 * \param [in] renum - it must be \c false.
5602 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5603 * delete using decrRef() as it is no more needed.
5605 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
5608 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5609 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5610 switch(meshDimRelToMax)
5616 return const_cast<MEDCouplingStructuredMesh *>(m);
5621 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5622 buildMinusOneImplicitPartIfNeeded();
5623 MEDCouplingMesh *ret(_faces_if_necessary);
5629 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5634 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5635 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5636 * \return int - the number of entities.
5637 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5639 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5641 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5643 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5644 switch(meshDimRelToMaxExt)
5647 return cmesh->getNumberOfCells();
5649 return cmesh->getNumberOfNodes();
5651 return cmesh->getNumberOfCellsOfSubLevelMesh();
5653 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5657 int MEDFileStructuredMesh::getNumberOfNodes() const
5659 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5661 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5662 return cmesh->getNumberOfNodes();
5665 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5667 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5669 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5670 switch(meshDimRelToMaxExt)
5673 return cmesh->getNumberOfCells();
5675 return cmesh->getNumberOfCellsOfSubLevelMesh();
5677 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5681 bool MEDFileStructuredMesh::hasImplicitPart() const
5687 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5689 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5691 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5692 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5695 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5696 if(cm.getReverseExtrudedType()!=gt)
5697 throw INTERP_KERNEL::Exception(MSG);
5698 buildImplicitPart();
5699 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5703 if(gt!=zeFaceMesh->getCellModelEnum())
5704 throw INTERP_KERNEL::Exception(MSG);
5705 return zeFaceMesh->getNumberOfCells();
5709 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5711 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5713 buildImplicitPart();
5716 void MEDFileStructuredMesh::buildImplicitPart() const
5718 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5720 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5721 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5724 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5726 _faces_if_necessary=0;
5730 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5731 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5733 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5735 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5737 return _faces_if_necessary;
5740 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5742 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5744 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5745 switch(meshDimRelToMax)
5749 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5754 int mdim(cmesh->getMeshDimension());
5756 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5757 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5761 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5765 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
5767 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5770 return getNumberOfCellsAtLevel(0);
5773 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5775 if(st.getNumberOfItems()!=1)
5776 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 !");
5777 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5778 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5779 if(getNumberOfNodes()!=(int)nodesFetched.size())
5780 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5781 if(st[0].getPflName().empty())
5783 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5786 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5787 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5788 int sz(nodesFetched.size());
5789 for(const int *work=arr->begin();work!=arr->end();work++)
5791 std::vector<int> conn;
5792 cmesh->getNodeIdsOfCell(*work,conn);
5793 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5794 if(*it>=0 && *it<sz)
5795 nodesFetched[*it]=true;
5797 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5801 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5803 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5807 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5808 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5810 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5811 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5813 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5816 if(!mrs || mrs->isCellFamilyFieldReading())
5818 famCells=DataArrayInt::New();
5819 famCells->alloc(nbOfElt,1);
5820 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
5823 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5826 if(!mrs || mrs->isCellNumFieldReading())
5828 numCells=DataArrayInt::New();
5829 numCells->alloc(nbOfElt,1);
5830 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
5833 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5836 if(!mrs || mrs->isCellNameFieldReading())
5838 namesCells=DataArrayAsciiChar::New();
5839 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5840 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
5841 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5846 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5848 setName(strm->getName());
5849 setDescription(strm->getDescription());
5850 setUnivName(strm->getUnivName());
5851 setIteration(strm->getIteration());
5852 setOrder(strm->getOrder());
5853 setTimeValue(strm->getTime());
5854 setTimeUnit(strm->getTimeUnit());
5855 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5856 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5857 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
5860 if(!mrs || mrs->isNodeFamilyFieldReading())
5862 int nbNodes(getNumberOfNodes());
5864 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5865 _fam_nodes=DataArrayInt::New();
5866 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5867 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...
5868 _fam_nodes->fillWithZero();
5869 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
5872 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5875 if(!mrs || mrs->isNodeNumFieldReading())
5877 _num_nodes=DataArrayInt::New();
5878 _num_nodes->alloc(nbOfElt,1);
5879 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
5882 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5885 if(!mrs || mrs->isNodeNameFieldReading())
5887 _names_nodes=DataArrayAsciiChar::New();
5888 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5889 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
5890 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5893 int meshDim(getStructuredMesh()->getMeshDimension());
5894 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5896 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5899 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5901 int meshDim(getStructuredMesh()->getMeshDimension());
5902 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5904 if((const DataArrayInt *)_fam_cells)
5905 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
5906 if((const DataArrayInt *)_fam_faces)
5907 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
5908 if((const DataArrayInt *)_fam_nodes)
5909 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
5910 if((const DataArrayInt *)_num_cells)
5911 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
5912 if((const DataArrayInt *)_num_faces)
5913 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
5914 if((const DataArrayInt *)_num_nodes)
5915 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
5916 if((const DataArrayAsciiChar *)_names_cells)
5918 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5920 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5921 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5922 throw INTERP_KERNEL::Exception(oss.str().c_str());
5924 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
5926 if((const DataArrayAsciiChar *)_names_faces)
5928 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5930 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5931 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5932 throw INTERP_KERNEL::Exception(oss.str().c_str());
5934 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
5936 if((const DataArrayAsciiChar *)_names_nodes)
5938 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5940 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5941 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5942 throw INTERP_KERNEL::Exception(oss.str().c_str());
5944 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
5947 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5951 * Returns an empty instance of MEDFileCMesh.
5952 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5953 * mesh using decrRef() as it is no more needed.
5955 MEDFileCMesh *MEDFileCMesh::New()
5957 return new MEDFileCMesh;
5961 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5962 * file. The first mesh in the file is loaded.
5963 * \param [in] fileName - the name of MED file to read.
5964 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5965 * mesh using decrRef() as it is no more needed.
5966 * \throw If the file is not readable.
5967 * \throw If there is no meshes in the file.
5968 * \throw If the mesh in the file is not a Cartesian one.
5970 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5972 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5975 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5976 throw INTERP_KERNEL::Exception(oss.str().c_str());
5978 MEDFileUtilities::CheckFileForRead(fileName);
5979 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5981 ParaMEDMEM::MEDCouplingMeshType meshType;
5983 ParaMEDMEM::MEDCouplingAxisType dummy3;
5984 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
5985 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5989 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5990 * file. The mesh to load is specified by its name and numbers of a time step and an
5992 * \param [in] fileName - the name of MED file to read.
5993 * \param [in] mName - the name of the mesh to read.
5994 * \param [in] dt - the number of a time step.
5995 * \param [in] it - the number of an iteration.
5996 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5997 * mesh using decrRef() as it is no more needed.
5998 * \throw If the file is not readable.
5999 * \throw If there is no mesh with given attributes in the file.
6000 * \throw If the mesh in the file is not a Cartesian one.
6002 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6004 MEDFileUtilities::CheckFileForRead(fileName);
6005 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6006 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6009 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6011 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6014 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6016 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6017 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6022 * Returns the dimension on cells in \a this mesh.
6023 * \return int - the mesh dimension.
6024 * \throw If there are no cells in this mesh.
6026 int MEDFileCMesh::getMeshDimension() const
6028 if(!((const MEDCouplingCMesh*)_cmesh))
6029 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6030 return _cmesh->getMeshDimension();
6034 * Returns the dimension on nodes in \a this mesh.
6035 * \return int - the space dimension.
6036 * \throw If there are no cells in this mesh.
6038 int MEDFileCMesh::getSpaceDimension() const
6040 if(!((const MEDCouplingCMesh*)_cmesh))
6041 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6042 return _cmesh->getSpaceDimension();
6046 * Returns a string describing \a this mesh.
6047 * \return std::string - the mesh information string.
6049 std::string MEDFileCMesh::simpleRepr() const
6051 return MEDFileStructuredMesh::simpleRepr();
6055 * Returns a full textual description of \a this mesh.
6056 * \return std::string - the string holding the mesh description.
6058 std::string MEDFileCMesh::advancedRepr() const
6060 return simpleRepr();
6063 MEDFileMesh *MEDFileCMesh::shallowCpy() const
6065 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6069 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6071 return new MEDFileCMesh;
6074 MEDFileMesh *MEDFileCMesh::deepCpy() const
6076 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6077 ret->deepCpyEquivalences(*this);
6078 if((const MEDCouplingCMesh*)_cmesh)
6079 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
6080 ret->deepCpyAttributes();
6085 * Checks if \a this and another mesh are equal.
6086 * \param [in] other - the mesh to compare with.
6087 * \param [in] eps - a precision used to compare real values.
6088 * \param [in,out] what - the string returning description of unequal data.
6089 * \return bool - \c true if the meshes are equal, \c false, else.
6091 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6093 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6095 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6098 what="Mesh types differ ! This is cartesian and other is NOT !";
6101 clearNonDiscrAttributes();
6102 otherC->clearNonDiscrAttributes();
6103 const MEDCouplingCMesh *coo1=_cmesh;
6104 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6105 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6107 what="Mismatch of cartesian meshes ! One is defined and not other !";
6112 bool ret=coo1->isEqual(coo2,eps);
6115 what="cartesian meshes differ !";
6123 * Clears redundant attributes of incorporated data arrays.
6125 void MEDFileCMesh::clearNonDiscrAttributes() const
6127 MEDFileStructuredMesh::clearNonDiscrAttributes();
6128 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6131 MEDFileCMesh::MEDFileCMesh()
6135 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6138 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6140 catch(INTERP_KERNEL::Exception& e)
6145 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6147 ParaMEDMEM::MEDCouplingMeshType meshType;
6150 ParaMEDMEM::MEDCouplingAxisType axType;
6151 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6152 if(meshType!=CARTESIAN)
6154 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6155 throw INTERP_KERNEL::Exception(oss.str().c_str());
6157 MEDFileCMeshL2 loaderl2;
6158 loaderl2.loadAll(fid,mid,mName,dt,it);
6159 setAxType(loaderl2.getAxType());
6160 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6163 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6167 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6168 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6170 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6172 synchronizeTinyInfoOnLeaves();
6176 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6178 synchronizeTinyInfoOnLeaves();
6183 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6184 * \param [in] m - the new MEDCouplingCMesh to refer to.
6185 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6188 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6190 dealWithTinyInfo(m);
6196 MEDFileMesh *MEDFileCMesh::cartesianize() const
6198 if(getAxType()==AX_CART)
6201 return const_cast<MEDFileCMesh *>(this);
6205 const MEDCouplingCMesh *cmesh(getMesh());
6207 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6208 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6209 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxType()));
6210 clmesh->setCoords(coords);
6211 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6212 ret->MEDFileStructuredMesh::operator=(*this);
6213 ret->setMesh(clmesh);
6214 ret->setAxType(AX_CART);
6219 void MEDFileCMesh::writeLL(med_idt fid) const
6221 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6222 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6223 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6224 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6225 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6226 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6227 int spaceDim(_cmesh->getSpaceDimension());
6228 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6229 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6230 for(int i=0;i<spaceDim;i++)
6232 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6234 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6235 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
6236 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
6238 // MED_CARTESIAN and not MEDFileMeshL2::TraduceAxisTypeRev(getAxType()) ! Yes it is not a bug. The discrimination is done in MEDmeshGridTypeWr.
6239 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
6241 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6242 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxType())));
6243 for(int i=0;i<spaceDim;i++)
6245 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6246 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6249 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6250 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6253 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6255 const MEDCouplingCMesh *cmesh=_cmesh;
6258 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6259 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6260 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6261 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6264 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6266 return new MEDFileCurveLinearMesh;
6269 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6271 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6274 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6275 throw INTERP_KERNEL::Exception(oss.str().c_str());
6277 MEDFileUtilities::CheckFileForRead(fileName);
6278 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6280 ParaMEDMEM::MEDCouplingMeshType meshType;
6281 ParaMEDMEM::MEDCouplingAxisType dummy3;
6283 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6284 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6287 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6289 MEDFileUtilities::CheckFileForRead(fileName);
6290 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6291 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6294 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6296 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6299 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6301 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6302 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6306 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6308 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6312 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6314 return new MEDFileCurveLinearMesh;
6317 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
6319 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6320 ret->deepCpyEquivalences(*this);
6321 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6322 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
6323 ret->deepCpyAttributes();
6327 int MEDFileCurveLinearMesh::getMeshDimension() const
6329 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6330 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6331 return _clmesh->getMeshDimension();
6334 std::string MEDFileCurveLinearMesh::simpleRepr() const
6336 return MEDFileStructuredMesh::simpleRepr();
6339 std::string MEDFileCurveLinearMesh::advancedRepr() const
6341 return simpleRepr();
6344 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6346 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6348 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6351 what="Mesh types differ ! This is curve linear and other is NOT !";
6354 clearNonDiscrAttributes();
6355 otherC->clearNonDiscrAttributes();
6356 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6357 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6358 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6360 what="Mismatch of curve linear meshes ! One is defined and not other !";
6365 bool ret=coo1->isEqual(coo2,eps);
6368 what="curve linear meshes differ !";
6375 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6377 MEDFileStructuredMesh::clearNonDiscrAttributes();
6378 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6381 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6383 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6386 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6387 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6388 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6389 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6392 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6394 synchronizeTinyInfoOnLeaves();
6398 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6400 dealWithTinyInfo(m);
6406 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6408 if(getAxType()==AX_CART)
6411 return const_cast<MEDFileCurveLinearMesh *>(this);
6415 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6417 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6418 const DataArrayDouble *coords(mesh->getCoords());
6420 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6421 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6422 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6423 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsCart(coords->cartesianize(getAxType()));
6424 mesh2->setCoords(coordsCart);
6425 ret->setMesh(mesh2);
6426 ret->setAxType(AX_CART);
6431 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6433 synchronizeTinyInfoOnLeaves();
6437 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6441 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6444 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6446 catch(INTERP_KERNEL::Exception& e)
6451 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6453 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6454 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6455 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6456 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6457 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6458 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6459 int spaceDim=_clmesh->getSpaceDimension();
6460 int meshDim=_clmesh->getMeshDimension();
6461 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6462 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6463 const DataArrayDouble *coords=_clmesh->getCoords();
6465 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6466 for(int i=0;i<spaceDim;i++)
6468 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6470 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6471 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
6472 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
6474 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),comp,unit));
6476 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6477 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6478 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6479 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6481 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6483 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6484 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6487 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6489 ParaMEDMEM::MEDCouplingMeshType meshType;
6492 ParaMEDMEM::MEDCouplingAxisType axType;
6493 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6495 if(meshType!=CURVE_LINEAR)
6497 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6498 throw INTERP_KERNEL::Exception(oss.str().c_str());
6500 MEDFileCLMeshL2 loaderl2;
6501 loaderl2.loadAll(fid,mid,mName,dt,it);
6502 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6505 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6508 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6510 return new MEDFileMeshMultiTS;
6513 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6515 return new MEDFileMeshMultiTS(fileName);
6518 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6520 return new MEDFileMeshMultiTS(fileName,mName);
6523 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6525 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6526 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6528 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6529 if((const MEDFileMesh *)*it)
6530 meshOneTs[i]=(*it)->deepCpy();
6531 ret->_mesh_one_ts=meshOneTs;
6535 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6537 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6540 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6542 std::vector<const BigMemoryObject *> ret;
6543 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6544 ret.push_back((const MEDFileMesh *)*it);
6548 std::string MEDFileMeshMultiTS::getName() const
6550 if(_mesh_one_ts.empty())
6551 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6552 return _mesh_one_ts[0]->getName();
6555 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6557 std::string oldName(getName());
6558 std::vector< std::pair<std::string,std::string> > v(1);
6559 v[0].first=oldName; v[0].second=newMeshName;
6563 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6566 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6568 MEDFileMesh *cur(*it);
6570 ret=cur->changeNames(modifTab) || ret;
6575 void MEDFileMeshMultiTS::cartesianizeMe()
6577 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6579 MEDFileMesh *cur(*it);
6582 MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
6588 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6590 if(_mesh_one_ts.empty())
6591 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6592 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6595 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6598 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6599 _mesh_one_ts.resize(1);
6600 mesh1TimeStep->incrRef();
6601 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6602 _mesh_one_ts[0]=mesh1TimeStep;
6605 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
6607 if ( MEDFileMesh* m = getOneTimeStep() )
6608 return m->getJoints();
6613 * \brief Set Joints that are common to all time-stamps
6615 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
6617 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6619 (*it)->setJoints( joints );
6623 void MEDFileMeshMultiTS::write(med_idt fid) const
6625 MEDFileJoints *joints(getJoints());
6626 bool jointsWritten(false);
6628 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6630 if ( jointsWritten )
6631 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
6633 jointsWritten = true;
6635 (*it)->copyOptionsFrom(*this);
6639 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
6642 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6644 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6645 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6646 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6647 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6651 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6653 MEDFileJoints* joints = 0;
6654 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
6656 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
6657 joints = getOneTimeStep()->getJoints();
6660 _mesh_one_ts.clear(); //for the moment to be improved
6661 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
6664 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6668 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6671 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6674 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6675 throw INTERP_KERNEL::Exception(oss.str().c_str());
6677 MEDFileUtilities::CheckFileForRead(fileName);
6678 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6680 ParaMEDMEM::MEDCouplingMeshType meshType;
6682 ParaMEDMEM::MEDCouplingAxisType dummy3;
6683 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6684 loadFromFile(fileName,ms.front());
6686 catch(INTERP_KERNEL::Exception& e)
6691 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6694 loadFromFile(fileName,mName);
6696 catch(INTERP_KERNEL::Exception& e)
6701 MEDFileMeshes *MEDFileMeshes::New()
6703 return new MEDFileMeshes;
6706 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6708 return new MEDFileMeshes(fileName);
6711 void MEDFileMeshes::write(med_idt fid) const
6714 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6716 (*it)->copyOptionsFrom(*this);
6721 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6723 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6724 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6725 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6726 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6731 int MEDFileMeshes::getNumberOfMeshes() const
6733 return _meshes.size();
6736 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6738 return new MEDFileMeshesIterator(this);
6741 /** Return a borrowed reference (caller is not responsible) */
6742 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6744 if(i<0 || i>=(int)_meshes.size())
6746 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6747 throw INTERP_KERNEL::Exception(oss.str().c_str());
6749 return _meshes[i]->getOneTimeStep();
6752 /** Return a borrowed reference (caller is not responsible) */
6753 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6755 std::vector<std::string> ms=getMeshesNames();
6756 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6759 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6760 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6761 throw INTERP_KERNEL::Exception(oss.str().c_str());
6763 return getMeshAtPos((int)std::distance(ms.begin(),it));
6766 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6768 std::vector<std::string> ret(_meshes.size());
6770 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6772 const MEDFileMeshMultiTS *f=(*it);
6775 ret[i]=f->getName();
6779 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6780 throw INTERP_KERNEL::Exception(oss.str().c_str());
6786 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6789 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6791 MEDFileMeshMultiTS *cur(*it);
6793 ret=cur->changeNames(modifTab) || ret;
6798 void MEDFileMeshes::cartesianizeMe()
6800 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6802 MEDFileMeshMultiTS *cur(*it);
6804 cur->cartesianizeMe();
6808 void MEDFileMeshes::resize(int newSize)
6810 _meshes.resize(newSize);
6813 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6816 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6817 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6818 elt->setOneTimeStep(mesh);
6819 _meshes.push_back(elt);
6822 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6825 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6826 if(i>=(int)_meshes.size())
6827 _meshes.resize(i+1);
6828 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6829 elt->setOneTimeStep(mesh);
6833 void MEDFileMeshes::destroyMeshAtPos(int i)
6835 if(i<0 || i>=(int)_meshes.size())
6837 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6838 throw INTERP_KERNEL::Exception(oss.str().c_str());
6840 _meshes.erase(_meshes.begin()+i);
6843 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6845 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6847 _meshes.resize(ms.size());
6848 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6849 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6852 MEDFileMeshes::MEDFileMeshes()
6856 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6859 loadFromFile(fileName);
6861 catch(INTERP_KERNEL::Exception& /*e*/)
6865 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6867 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6869 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6870 if((const MEDFileMeshMultiTS *)*it)
6871 meshes[i]=(*it)->deepCpy();
6872 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6873 ret->_meshes=meshes;
6877 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6879 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6882 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6884 std::vector<const BigMemoryObject *> ret;
6885 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6886 ret.push_back((const MEDFileMeshMultiTS *)*it);
6890 std::string MEDFileMeshes::simpleRepr() const
6892 std::ostringstream oss;
6893 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6894 simpleReprWithoutHeader(oss);
6898 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6900 int nbOfMeshes=getNumberOfMeshes();
6901 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6902 std::vector<std::string> mns=getMeshesNames();
6903 for(int i=0;i<nbOfMeshes;i++)
6904 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6907 void MEDFileMeshes::checkCoherency() const
6909 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6911 std::set<std::string> s;
6912 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6914 const MEDFileMeshMultiTS *elt=(*it);
6917 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6918 throw INTERP_KERNEL::Exception(oss.str().c_str());
6920 std::size_t sz=s.size();
6921 s.insert(std::string((*it)->getName()));
6924 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6925 throw INTERP_KERNEL::Exception(oss.str().c_str());
6930 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6935 _nb_iter=ms->getNumberOfMeshes();
6939 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6943 MEDFileMesh *MEDFileMeshesIterator::nextt()
6945 if(_iter_id<_nb_iter)
6947 MEDFileMeshes *ms(_ms);
6949 return ms->getMeshAtPos(_iter_id++);