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 MEDCoupling;
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 MEDCoupling::MEDCouplingMeshType meshType;
87 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
90 MEDCoupling::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 MEDCoupling::MEDCouplingMeshType meshType;
141 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
144 MEDCoupling::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);
532 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
533 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
534 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
537 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
539 std::vector<std::string> ret;
540 std::vector<std::string> allGrps(getGroupsNames());
541 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
543 std::vector<int> levs(getGrpNonEmptyLevelsExt((*it)));
544 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
551 * Returns all relative mesh levels (including nodes) where a given group is defined.
552 * \param [in] grp - the name of the group of interest.
553 * \return std::vector<int> - a sequence of the relative dimensions.
555 std::vector<int> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
557 std::vector<std::string> fams(getFamiliesOnGroup(grp));
558 return getFamsNonEmptyLevelsExt(fams);
562 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
563 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
564 * \param [in] grps - a sequence of names of the groups of interest.
565 * \return std::vector<int> - a sequence of the relative dimensions.
567 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
569 std::vector<std::string> fams(getFamiliesOnGroups(grps));
570 return getFamsNonEmptyLevels(fams);
574 * Returns all relative mesh levels (including nodes) where given groups are defined.
575 * \param [in] grps - a sequence of names of the groups of interest.
576 * \return std::vector<int> - a sequence of the relative dimensions.
578 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
580 std::vector<std::string> fams(getFamiliesOnGroups(grps));
581 return getFamsNonEmptyLevelsExt(fams);
585 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
586 * To include nodes, call getGrpNonEmptyLevelsExt() method.
587 * \param [in] grp - the name of the group of interest.
588 * \return std::vector<int> - a sequence of the relative dimensions.
590 std::vector<int> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
592 std::vector<std::string> fams(getFamiliesOnGroup(grp));
593 return getFamsNonEmptyLevels(fams);
597 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
598 * To include nodes, call getFamNonEmptyLevelsExt() method.
599 * \param [in] fam - the name of the family of interest.
600 * \return std::vector<int> - a sequence of the relative dimensions.
602 std::vector<int> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
604 std::vector<std::string> fams(1,std::string(fam));
605 return getFamsNonEmptyLevels(fams);
609 * Returns all relative mesh levels (including nodes) where a given family is defined.
610 * \param [in] fam - the name of the family of interest.
611 * \return std::vector<int> - a sequence of the relative dimensions.
613 std::vector<int> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
615 std::vector<std::string> fams(1,std::string(fam));
616 return getFamsNonEmptyLevelsExt(fams);
619 std::string MEDFileMesh::GetMagicFamilyStr()
621 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
625 * Changes a name of every family, included in one group only, to be same as the group name.
626 * \throw If there are families with equal names in \a this mesh.
628 void MEDFileMesh::assignFamilyNameWithGroupName()
630 std::map<std::string, std::vector<std::string> > groups(_groups);
631 std::map<std::string,int> newFams;
632 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
634 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
635 if(grps.size()==1 && groups[grps[0]].size()==1)
637 if(newFams.find(grps[0])!=newFams.end())
639 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
640 throw INTERP_KERNEL::Exception(oss.str().c_str());
642 newFams[grps[0]]=(*it).second;
643 std::vector<std::string>& grps2=groups[grps[0]];
644 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
649 if(newFams.find((*it).first)!=newFams.end())
651 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
652 throw INTERP_KERNEL::Exception(oss.str().c_str());
654 newFams[(*it).first]=(*it).second;
662 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
664 * \return the removed groups.
666 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
668 std::vector<std::string> ret;
669 std::map<std::string, std::vector<std::string> > newGrps;
670 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
672 if((*it).second.empty())
673 ret.push_back((*it).first);
675 newGrps[(*it).first]=(*it).second;
683 * Removes a group from \a this mesh.
684 * \param [in] name - the name of the group to remove.
685 * \throw If no group with such a \a name exists.
687 void MEDFileMesh::removeGroup(const std::string& name)
689 std::string oname(name);
690 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
691 std::vector<std::string> grps=getGroupsNames();
692 if(it==_groups.end())
694 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
695 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
696 throw INTERP_KERNEL::Exception(oss.str().c_str());
702 * Removes a family from \a this mesh.
703 * \param [in] name - the name of the family to remove.
704 * \throw If no family with such a \a name exists.
706 void MEDFileMesh::removeFamily(const std::string& name)
708 std::string oname(name);
709 std::map<std::string, int >::iterator it=_families.find(oname);
710 std::vector<std::string> fams=getFamiliesNames();
711 if(it==_families.end())
713 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
714 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
715 throw INTERP_KERNEL::Exception(oss.str().c_str());
718 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
720 std::vector<std::string>& v=(*it3).second;
721 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
728 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
729 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
730 * family field whatever its level. This method also suppresses the orphan families.
732 * \return - The list of removed groups names.
734 * \sa MEDFileMesh::removeOrphanFamilies.
736 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
738 removeOrphanFamilies();
739 return removeEmptyGroups();
743 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
744 * 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.
746 * \return - The list of removed families names.
747 * \sa MEDFileMesh::removeOrphanGroups.
749 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
751 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
752 std::vector<std::string> ret;
753 if(!((DataArrayInt*)allFamIdsInUse))
755 ret=getFamiliesNames();
756 _families.clear(); _groups.clear();
759 std::map<std::string,int> famMap;
760 std::map<std::string, std::vector<std::string> > grps(_groups);
761 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
763 if(allFamIdsInUse->presenceOfValue((*it).second))
764 famMap[(*it).first]=(*it).second;
767 ret.push_back((*it).first);
768 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
769 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
771 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
772 std::vector<std::string>& famv=(*it3).second;
773 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
779 { _families=famMap; _groups=grps; }
784 * 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
785 * this family is orphan or not.
787 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
789 void MEDFileMesh::removeFamiliesReferedByNoGroups()
791 std::map<std::string,int> fams;
792 std::set<std::string> sfams;
793 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
794 sfams.insert((*it).first);
795 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
796 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
798 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
799 if(*it!=DFT_FAM_NAME)
800 _families.erase(*it);
804 * 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
805 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
806 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
808 * \sa MEDFileMesh::removeOrphanFamilies
810 void MEDFileMesh::rearrangeFamilies()
812 checkOrphanFamilyZero();
813 removeFamiliesReferedByNoGroups();
815 std::vector<int> levels(getNonEmptyLevelsExt());
816 std::set<int> idsRefed;
817 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
818 idsRefed.insert((*it).second);
819 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
821 const DataArrayInt *fams(0);
824 fams=getFamilyFieldAtLevel(*it);
826 catch(INTERP_KERNEL::Exception& e) { }
829 std::vector<bool> v(fams->getNumberOfTuples(),false);
830 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
831 fams->switchOnTupleEqualTo(*pt,v);
832 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
833 if(!unfetchedIds->empty())
835 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
836 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
837 setFamilyFieldArr(*it,newFams);
840 removeOrphanFamilies();
844 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
846 void MEDFileMesh::checkOrphanFamilyZero() const
848 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
850 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
852 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
853 throw INTERP_KERNEL::Exception(oss.str().c_str());
859 * Renames a group in \a this mesh.
860 * \param [in] oldName - a current name of the group to rename.
861 * \param [in] newName - a new group name.
862 * \throw If no group named \a oldName exists in \a this mesh.
863 * \throw If a group named \a newName already exists.
865 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
867 std::string oname(oldName);
868 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
869 std::vector<std::string> grps=getGroupsNames();
870 if(it==_groups.end())
872 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
873 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
874 throw INTERP_KERNEL::Exception(oss.str().c_str());
876 std::string nname(newName);
877 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
878 if(it2!=_groups.end())
880 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
881 throw INTERP_KERNEL::Exception(oss.str().c_str());
883 std::vector<std::string> cpy=(*it).second;
885 _groups[newName]=cpy;
889 * Changes an id of a family in \a this mesh.
890 * This method calls changeFamilyIdArr().
891 * \param [in] oldId - a current id of the family.
892 * \param [in] newId - a new family id.
894 void MEDFileMesh::changeFamilyId(int oldId, int newId)
896 changeFamilyIdArr(oldId,newId);
897 std::map<std::string,int> fam2;
898 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
900 if((*it).second==oldId)
901 fam2[(*it).first]=newId;
903 fam2[(*it).first]=(*it).second;
909 * Renames a family in \a this mesh.
910 * \param [in] oldName - a current name of the family to rename.
911 * \param [in] newName - a new family name.
912 * \throw If no family named \a oldName exists in \a this mesh.
913 * \throw If a family named \a newName already exists.
915 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
917 std::string oname(oldName);
918 std::map<std::string, int >::iterator it=_families.find(oname);
919 std::vector<std::string> fams=getFamiliesNames();
920 if(it==_families.end())
922 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
923 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
924 throw INTERP_KERNEL::Exception(oss.str().c_str());
926 std::string nname(newName);
927 std::map<std::string, int >::iterator it2=_families.find(nname);
928 if(it2!=_families.end())
930 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
931 throw INTERP_KERNEL::Exception(oss.str().c_str());
933 int cpy=(*it).second;
935 _families[newName]=cpy;
936 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
938 std::vector<std::string>& v=(*it3).second;
939 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
946 * Checks if \a this and another mesh contains the same families.
947 * \param [in] other - the mesh to compare with \a this one.
948 * \param [in,out] what - an unused parameter.
949 * \return bool - \c true if number of families and their ids are the same in the two
950 * meshes. Families with the id == \c 0 are not considered.
952 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
954 if(_families==other->_families)
956 std::map<std::string,int> fam0;
957 std::map<std::string,int> fam1;
958 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
960 fam0[(*it).first]=(*it).second;
961 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
963 fam1[(*it).first]=(*it).second;
968 * Checks if \a this and another mesh contains the same groups.
969 * \param [in] other - the mesh to compare with \a this one.
970 * \param [in,out] what - a string describing a difference of groups of the two meshes
971 * in case if this method returns \c false.
972 * \return bool - \c true if number of groups and families constituting them are the
973 * same in the two meshes.
975 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
977 if(_groups==other->_groups)
980 std::size_t sz=_groups.size();
981 if(sz!=other->_groups.size())
983 what="Groups differ because not same number !\n";
988 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
989 for(std::size_t i=0;i<sz && ret;i++,it1++)
991 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
992 if(it2!=other->_groups.end())
994 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
995 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1001 what="A group in first mesh exists not in other !\n";
1007 std::ostringstream oss; oss << "Groups description differs :\n";
1008 oss << "First group description :\n";
1009 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1011 oss << " Group \"" << (*it).first << "\" on following families :\n";
1012 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1013 oss << " \"" << *it2 << "\n";
1015 oss << "Second group description :\n";
1016 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1018 oss << " Group \"" << (*it).first << "\" on following families :\n";
1019 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1020 oss << " \"" << *it2 << "\n";
1028 * Checks if a group with a given name exists in \a this mesh.
1029 * \param [in] groupName - the group name.
1030 * \return bool - \c true the group \a groupName exists in \a this mesh.
1032 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1034 std::string grpName(groupName);
1035 return _groups.find(grpName)!=_groups.end();
1039 * Checks if a family with a given id exists in \a this mesh.
1040 * \param [in] famId - the family id.
1041 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1043 bool MEDFileMesh::existsFamily(int famId) const
1045 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1046 if((*it2).second==famId)
1052 * Checks if a family with a given name exists in \a this mesh.
1053 * \param [in] familyName - the family name.
1054 * \return bool - \c true the family \a familyName exists in \a this mesh.
1056 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1058 std::string fname(familyName);
1059 return _families.find(fname)!=_families.end();
1063 * Sets an id of a family.
1064 * \param [in] familyName - the family name.
1065 * \param [in] id - a new id of the family.
1067 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1069 std::string fname(familyName);
1070 _families[fname]=id;
1073 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1075 std::string fname(familyName);
1076 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1077 if((*it).second==id)
1079 if((*it).first!=familyName)
1081 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1082 throw INTERP_KERNEL::Exception(oss.str().c_str());
1085 _families[fname]=id;
1089 * Adds a family to \a this mesh.
1090 * \param [in] familyName - a name of the family.
1091 * \param [in] famId - an id of the family.
1092 * \throw If a family with the same name or id already exists in \a this mesh.
1094 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1096 std::string fname(familyName);
1097 std::map<std::string,int>::const_iterator it=_families.find(fname);
1098 if(it==_families.end())
1100 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1101 if((*it2).second==famId)
1103 std::ostringstream oss;
1104 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1105 throw INTERP_KERNEL::Exception(oss.str().c_str());
1107 _families[fname]=famId;
1111 if((*it).second!=famId)
1113 std::ostringstream oss;
1114 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1115 throw INTERP_KERNEL::Exception(oss.str().c_str());
1121 * Creates a group including all mesh entities of given dimension.
1122 * \warning This method does \b not guarantee that the created group includes mesh
1123 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1124 * present in family fields of different dimensions. To assure this, call
1125 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1126 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1128 * \param [in] groupName - a name of the new group.
1129 * \throw If a group named \a groupName already exists.
1130 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1131 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1133 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1135 std::string grpName(groupName);
1136 std::vector<int> levs=getNonEmptyLevelsExt();
1137 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1139 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1140 oss << "Available relative ext levels are : ";
1141 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1142 throw INTERP_KERNEL::Exception(oss.str().c_str());
1144 if(existsGroup(groupName))
1146 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1147 oss << "Already existing groups are : ";
1148 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1149 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1150 throw INTERP_KERNEL::Exception(oss.str().c_str());
1152 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1154 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1155 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1156 std::vector<std::string> familiesOnWholeGroup;
1157 for(const int *it=famIds->begin();it!=famIds->end();it++)
1160 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1162 _groups[grpName]=familiesOnWholeGroup;
1166 * Ensures that given family ids do not present in family fields of dimensions different
1167 * than given ones. If a family id is present in the family fields of dimensions different
1168 * than the given ones, a new family is created and the whole data is updated accordingly.
1169 * \param [in] famIds - a sequence of family ids to check.
1170 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1171 * famIds should exclusively belong.
1172 * \return bool - \c true if no modification is done in \a this mesh by this method.
1174 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1176 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1177 std::vector<int> levs=getNonEmptyLevelsExt();
1178 std::set<int> levs2(levs.begin(),levs.end());
1179 std::vector<int> levsToTest;
1180 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1181 std::set<int> famIds2(famIds.begin(),famIds.end());
1184 if(!_families.empty())
1185 maxFamId=getMaxFamilyId()+1;
1186 std::vector<std::string> allFams=getFamiliesNames();
1187 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1189 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1192 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1193 std::vector<int> tmp;
1194 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1195 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1198 std::string famName=getFamilyNameGivenId(*it2);
1199 std::ostringstream oss; oss << "Family_" << maxFamId;
1200 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1201 addFamilyOnAllGroupsHaving(famName,zeName);
1202 _families[zeName]=maxFamId;
1203 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1212 * Adds a family to a given group in \a this mesh. If the group with a given name does
1213 * not exist, it is created.
1214 * \param [in] grpName - the name of the group to add the family in.
1215 * \param [in] famName - the name of the family to add to the group named \a grpName.
1216 * \throw If \a grpName or \a famName is an empty string.
1217 * \throw If no family named \a famName is present in \a this mesh.
1219 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1221 std::string grpn(grpName);
1222 std::string famn(famName);
1223 if(grpn.empty() || famn.empty())
1224 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1225 std::vector<std::string> fams=getFamiliesNames();
1226 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1228 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1229 oss << "Create this family or choose an existing one ! Existing fams are : ";
1230 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1231 throw INTERP_KERNEL::Exception(oss.str().c_str());
1233 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1234 if(it==_groups.end())
1236 _groups[grpn].push_back(famn);
1240 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1241 if(it2==(*it).second.end())
1242 (*it).second.push_back(famn);
1247 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1248 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1249 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1251 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1253 std::string famNameCpp(famName);
1254 std::string otherCpp(otherFamName);
1255 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1257 std::vector<std::string>& v=(*it).second;
1258 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1260 v.push_back(otherCpp);
1266 * \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).
1267 * \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)
1269 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1272 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1273 std::string grpName(ids->getName());
1275 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1276 ids->checkStrictlyMonotonic(true);
1277 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
1278 std::vector<std::string> grpsNames=getGroupsNames();
1279 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1281 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1282 throw INTERP_KERNEL::Exception(oss.str().c_str());
1284 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1285 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1286 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1287 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1288 std::vector<int> familyIds;
1289 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
1290 int maxVal=getTheMaxAbsFamilyId()+1;
1291 std::map<std::string,int> families(_families);
1292 std::map<std::string, std::vector<std::string> > groups(_groups);
1293 std::vector<std::string> fams;
1294 bool created(false);
1295 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1297 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
1298 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1299 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
1300 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1303 bool isFamPresent=false;
1304 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1305 isFamPresent=(*itl)->presenceOfValue(*famId);
1307 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1310 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1311 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1312 fams.push_back(locFamName);
1313 if(existsFamily(*famId))
1315 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1316 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1319 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1323 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1324 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1325 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1326 if(existsFamily(*famId))
1328 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1329 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1334 for(std::size_t i=0;i<familyIds.size();i++)
1336 DataArrayInt *da=idsPerfamiliyIds[i];
1337 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1341 _groups[grpName]=fams;
1344 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1346 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1349 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1351 std::string fam(familyNameToChange);
1352 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1354 std::vector<std::string>& fams((*it).second);
1355 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1359 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1365 * Returns a name of the family having a given id or, if no such a family exists, creates
1366 * a new uniquely named family and returns its name.
1367 * \param [in] id - the id of the family whose name is required.
1368 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1369 * \return std::string - the name of the existing or the created family.
1370 * \throw If it is not possible to create a unique family name.
1372 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1374 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1378 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1379 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1380 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1381 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1383 * This method will throws an exception if it is not possible to create a unique family name.
1385 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1387 std::vector<std::string> famAlreadyExisting(families.size());
1389 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1391 if((*it).second!=id)
1393 famAlreadyExisting[ii]=(*it).first;
1402 std::ostringstream oss; oss << "Family_" << id;
1403 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1409 * Sets names and ids of all families in \a this mesh.
1410 * \param [in] info - a map of a family name to a family id.
1412 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1418 * Sets names of all groups and families constituting them in \a this mesh.
1419 * \param [in] info - a map of a group name to a vector of names of families
1420 * constituting the group.
1422 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1428 * Returns an id of the family having a given name.
1429 * \param [in] name - the name of the family of interest.
1430 * \return int - the id of the family of interest.
1431 * \throw If no family with such a \a name exists.
1433 int MEDFileMesh::getFamilyId(const std::string& name) const
1435 std::string oname(name);
1436 std::map<std::string, int>::const_iterator it=_families.find(oname);
1437 std::vector<std::string> fams=getFamiliesNames();
1438 if(it==_families.end())
1440 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1441 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1442 throw INTERP_KERNEL::Exception(oss.str().c_str());
1444 return (*it).second;
1448 * Returns ids of the families having given names.
1449 * \param [in] fams - a sequence of the names of families of interest.
1450 * \return std::vector<int> - a sequence of the ids of families of interest.
1451 * \throw If \a fams contains a name of an inexistent family.
1453 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1455 std::vector<int> ret(fams.size());
1457 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1459 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1460 if(it2==_families.end())
1462 std::vector<std::string> fams2=getFamiliesNames();
1463 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1464 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1465 throw INTERP_KERNEL::Exception(oss.str().c_str());
1467 ret[i]=(*it2).second;
1473 * Returns a maximal abs(id) of families in \a this mesh.
1474 * \return int - the maximal norm of family id.
1475 * \throw If there are no families in \a this mesh.
1477 int MEDFileMesh::getMaxAbsFamilyId() const
1479 if(_families.empty())
1480 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1481 int ret=-std::numeric_limits<int>::max();
1482 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1484 ret=std::max(std::abs((*it).second),ret);
1490 * Returns a maximal id of families in \a this mesh.
1491 * \return int - the maximal family id.
1492 * \throw If there are no families in \a this mesh.
1494 int MEDFileMesh::getMaxFamilyId() const
1496 if(_families.empty())
1497 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1498 int ret=-std::numeric_limits<int>::max();
1499 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1501 ret=std::max((*it).second,ret);
1507 * Returns a minimal id of families in \a this mesh.
1508 * \return int - the minimal family id.
1509 * \throw If there are no families in \a this mesh.
1511 int MEDFileMesh::getMinFamilyId() const
1513 if(_families.empty())
1514 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1515 int ret=std::numeric_limits<int>::max();
1516 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1518 ret=std::min((*it).second,ret);
1524 * Returns a maximal id of families in \a this mesh. Not only named families are
1525 * considered but all family fields as well.
1526 * \return int - the maximal family id.
1528 int MEDFileMesh::getTheMaxAbsFamilyId() const
1530 int m1=-std::numeric_limits<int>::max();
1531 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1532 m1=std::max(std::abs((*it).second),m1);
1533 int m2=getMaxAbsFamilyIdInArrays();
1534 return std::max(m1,m2);
1538 * Returns a maximal id of families in \a this mesh. Not only named families are
1539 * considered but all family fields as well.
1540 * \return int - the maximal family id.
1542 int MEDFileMesh::getTheMaxFamilyId() const
1544 int m1=-std::numeric_limits<int>::max();
1545 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1546 m1=std::max((*it).second,m1);
1547 int m2=getMaxFamilyIdInArrays();
1548 return std::max(m1,m2);
1552 * Returns a minimal id of families in \a this mesh. Not only named families are
1553 * considered but all family fields as well.
1554 * \return int - the minimal family id.
1556 int MEDFileMesh::getTheMinFamilyId() const
1558 int m1=std::numeric_limits<int>::max();
1559 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1560 m1=std::min((*it).second,m1);
1561 int m2=getMinFamilyIdInArrays();
1562 return std::min(m1,m2);
1566 * This method only considers the maps. The contain of family array is ignored here.
1568 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1570 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1572 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1574 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1575 v.insert((*it).second);
1576 ret->alloc((int)v.size(),1);
1577 std::copy(v.begin(),v.end(),ret->getPointer());
1582 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1584 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1586 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1588 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1589 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1590 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1592 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1593 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1594 if((DataArrayInt *) ret)
1595 ret=dv->buildUnion(ret);
1603 * true is returned if no modification has been needed. false if family
1604 * renumbering has been needed.
1606 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1608 std::vector<int> levs=getNonEmptyLevelsExt();
1609 std::set<int> allFamIds;
1610 int maxId=getMaxFamilyId()+1;
1611 std::map<int,std::vector<int> > famIdsToRenum;
1612 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1614 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1617 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1619 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1621 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1623 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1626 if(famIdsToRenum.empty())
1628 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1629 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1631 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1632 int *famIdsToChange=fam->getPointer();
1633 std::map<int,int> ren;
1634 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1636 if(allIds->presenceOfValue(*it3))
1638 std::string famName=getFamilyNameGivenId(*it3);
1639 std::vector<std::string> grps=getGroupsOnFamily(famName);
1642 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1643 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1644 addFamilyOnGrp((*it4),newFam);
1647 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1648 for(const int *id=ids->begin();id!=ids->end();id++)
1649 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1655 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1656 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1657 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1658 * This method will throw an exception if a same family id is detected in different level.
1659 * \warning This policy is the opposite of those in MED file documentation ...
1661 void MEDFileMesh::normalizeFamIdsTrio()
1663 ensureDifferentFamIdsPerLevel();
1664 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1665 std::vector<int> levs=getNonEmptyLevelsExt();
1666 std::set<int> levsS(levs.begin(),levs.end());
1667 std::set<std::string> famsFetched;
1668 std::map<std::string,int> families;
1669 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1672 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1676 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1677 std::map<int,int> ren;
1678 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1680 int nbOfTuples=fam->getNumberOfTuples();
1681 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1682 for(int *w=start;w!=start+nbOfTuples;w++)
1684 for(const int *it=tmp->begin();it!=tmp->end();it++)
1686 if(allIds->presenceOfValue(*it))
1688 std::string famName=getFamilyNameGivenId(*it);
1689 families[famName]=ren[*it];
1690 famsFetched.insert(famName);
1695 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1698 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1702 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1703 std::map<int,int> ren;
1704 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1706 int nbOfTuples=fam->getNumberOfTuples();
1707 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1708 for(int *w=start;w!=start+nbOfTuples;w++)
1710 for(const int *it=tmp->begin();it!=tmp->end();it++)
1712 if(allIds->presenceOfValue(*it))
1714 std::string famName=getFamilyNameGivenId(*it);
1715 families[famName]=ren[*it];
1716 famsFetched.insert(famName);
1721 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1723 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1726 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1727 fam->fillWithZero();
1728 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1729 if(allIds->presenceOfValue(*it3))
1731 std::string famName=getFamilyNameGivenId(*it3);
1732 families[famName]=0;
1733 famsFetched.insert(famName);
1738 std::vector<std::string> allFams=getFamiliesNames();
1739 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1740 std::set<std::string> unFetchedIds;
1741 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1742 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1743 families[*it4]=_families[*it4];
1748 * This method normalizes fam id with the following policy.
1749 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1750 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1751 * This method will throw an exception if a same family id is detected in different level.
1753 void MEDFileMesh::normalizeFamIdsMEDFile()
1755 ensureDifferentFamIdsPerLevel();
1756 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1757 std::vector<int> levs=getNonEmptyLevelsExt();
1758 std::set<int> levsS(levs.begin(),levs.end());
1759 std::set<std::string> famsFetched;
1760 std::map<std::string,int> families;
1762 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1765 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1768 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1769 std::map<int,int> ren;
1770 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1772 int nbOfTuples=fam->getNumberOfTuples();
1773 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1774 for(int *w=start;w!=start+nbOfTuples;w++)
1776 for(const int *it=tmp->begin();it!=tmp->end();it++)
1778 if(allIds->presenceOfValue(*it))
1780 std::string famName=getFamilyNameGivenId(*it);
1781 families[famName]=ren[*it];
1782 famsFetched.insert(famName);
1788 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1790 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1793 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1794 std::map<int,int> ren;
1795 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1797 int nbOfTuples=fam->getNumberOfTuples();
1798 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1799 for(int *w=start;w!=start+nbOfTuples;w++)
1801 for(const int *it=tmp->begin();it!=tmp->end();it++)
1803 if(allIds->presenceOfValue(*it))
1805 std::string famName=getFamilyNameGivenId(*it);
1806 families[famName]=ren[*it];
1807 famsFetched.insert(famName);
1813 std::vector<std::string> allFams=getFamiliesNames();
1814 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1815 std::set<std::string> unFetchedIds;
1816 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1817 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1818 families[*it4]=_families[*it4];
1823 * Returns a name of the family by its id. If there are several families having the given
1824 * id, the name first in lexical order is returned.
1825 * \param [in] id - the id of the family whose name is required.
1826 * \return std::string - the name of the found family.
1827 * \throw If no family with the given \a id exists.
1829 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1831 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1832 if((*it).second==id)
1834 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1835 throw INTERP_KERNEL::Exception(oss.str().c_str());
1839 * Returns a string describing \a this mesh. This description includes the mesh name and
1840 * the mesh description string.
1841 * \return std::string - the mesh information string.
1843 std::string MEDFileMesh::simpleRepr() const
1845 std::ostringstream oss;
1846 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1847 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1848 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1853 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1854 * an empty one is created.
1856 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1858 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1861 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
1862 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1863 arr->fillWithZero();
1864 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1865 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1869 * Returns ids of mesh entities contained in a given group of a given dimension.
1870 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1872 * \param [in] grp - the name of the group of interest.
1873 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1874 * returned instead of ids.
1875 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1876 * numbers, if available and required, of mesh entities of the group. The caller
1877 * is to delete this array using decrRef() as it is no more needed.
1878 * \throw If the name of a nonexistent group is specified.
1879 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1881 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1883 std::vector<std::string> tmp(1);
1885 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1891 * Returns ids of mesh entities contained in given groups of a given dimension.
1892 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1894 * \param [in] grps - the names of the groups of interest.
1895 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1896 * returned instead of ids.
1897 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1898 * numbers, if available and required, of mesh entities of the groups. The caller
1899 * is to delete this array using decrRef() as it is no more needed.
1900 * \throw If the name of a nonexistent group is present in \a grps.
1901 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1903 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1905 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1906 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1910 * Returns ids of mesh entities contained in a given family of a given dimension.
1911 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1913 * \param [in] fam - the name of the family of interest.
1914 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1915 * returned instead of ids.
1916 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1917 * numbers, if available and required, of mesh entities of the family. The caller
1918 * is to delete this array using decrRef() as it is no more needed.
1919 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1921 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1923 std::vector<std::string> tmp(1);
1925 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1931 * Returns ids of nodes contained in a given group.
1932 * \param [in] grp - the name of the group of interest.
1933 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1934 * returned instead of ids.
1935 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1936 * numbers, if available and required, of nodes of the group. The caller
1937 * is to delete this array using decrRef() as it is no more needed.
1938 * \throw If the name of a nonexistent group is specified.
1939 * \throw If the family field is missing for nodes.
1941 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1943 std::vector<std::string> tmp(1);
1945 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1951 * Returns ids of nodes contained in given groups.
1952 * \param [in] grps - the names of the groups of interest.
1953 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1954 * returned instead of ids.
1955 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1956 * numbers, if available and required, of nodes of the groups. The caller
1957 * is to delete this array using decrRef() as it is no more needed.
1958 * \throw If the name of a nonexistent group is present in \a grps.
1959 * \throw If the family field is missing for nodes.
1961 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1963 return getGroupsArr(1,grps,renum);
1967 * Returns ids of nodes contained in a given group.
1968 * \param [in] grp - the name of the group of interest.
1969 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1970 * returned instead of ids.
1971 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1972 * numbers, if available and required, of nodes of the group. The caller
1973 * is to delete this array using decrRef() as it is no more needed.
1974 * \throw If the name of a nonexistent group is specified.
1975 * \throw If the family field is missing for nodes.
1977 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1979 std::vector<std::string> tmp(1);
1981 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1987 * Returns ids of nodes contained in given families.
1988 * \param [in] fams - the names of the families of interest.
1989 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1990 * returned instead of ids.
1991 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1992 * numbers, if available and required, of nodes of the families. The caller
1993 * is to delete this array using decrRef() as it is no more needed.
1994 * \throw If the family field is missing for nodes.
1996 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1998 return getFamiliesArr(1,fams,renum);
2002 * Adds groups of given dimension and creates corresponding families and family fields
2003 * given ids of mesh entities of each group.
2004 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2005 * \param [in] grps - a sequence of arrays of ids each describing a group.
2006 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2008 * \throw If names of some groups in \a grps are equal.
2009 * \throw If \a grps includes a group with an empty name.
2010 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2011 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2013 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2017 std::set<std::string> grpsName;
2018 std::vector<std::string> grpsName2(grps.size());
2021 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2023 grpsName.insert((*it)->getName());
2024 grpsName2[i]=(*it)->getName();
2026 if(grpsName.size()!=grps.size())
2027 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2028 if(grpsName.find(std::string(""))!=grpsName.end())
2029 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2030 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2031 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
2032 std::vector< std::vector<int> > fidsOfGroups;
2035 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2039 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
2040 for(unsigned int ii=0;ii<grps.size();ii++)
2042 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2043 grps2[ii]->setName(grps[ii]->getName());
2045 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2046 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2049 if(!_families.empty())
2050 offset=getMaxAbsFamilyId()+1;
2051 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2052 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
2053 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2054 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2058 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2059 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2060 * For the moment, the two last input parameters are not taken into account.
2062 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2064 std::map<int,std::string> famInv;
2065 for(const int *it=famIds->begin();it!=famIds->end();it++)
2067 std::ostringstream oss;
2068 oss << "Family_" << (*it);
2069 _families[oss.str()]=(*it);
2070 famInv[*it]=oss.str();
2073 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2075 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2077 _groups[grpNames[i]].push_back(famInv[*it2]);
2082 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2084 std::vector<int> levs(getNonEmptyLevels());
2085 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2086 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2088 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2089 ret.insert(ret.end(),elts.begin(),elts.end());
2094 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2096 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2097 return mLev->getDistributionOfTypes();
2100 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2102 loadLL(fid,mName,dt,it,mrs);
2103 loadJointsFromFile(fid);
2104 loadEquivalences(fid);
2107 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2109 famArr->applyLin(offset>0?1:-1,offset,0);
2110 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2113 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2114 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2119 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2120 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2121 * If this method fails to find such a name it will throw an exception.
2123 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2126 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2129 std::size_t len=nameTry.length();
2130 for(std::size_t ii=1;ii<len;ii++)
2132 std::string tmp=nameTry.substr(ii,len-ii);
2133 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2139 for(std::size_t i=1;i<30;i++)
2141 std::string tmp1(nameTry.at(0),i);
2143 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2149 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2151 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2153 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2156 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2158 std::size_t nbOfChunks=code.size()/3;
2159 if(code.size()%3!=0)
2160 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2162 for(std::size_t i=0;i<nbOfChunks;i++)
2171 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2172 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2173 * If _name is not empty and that 'm' has the same name nothing is done.
2174 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2176 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2179 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2184 std::string name(m->getName());
2189 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2190 oss << name << "' ! Names must match !";
2191 throw INTERP_KERNEL::Exception(oss.str().c_str());
2195 if(_desc_name.empty())
2196 _desc_name=m->getDescription();
2199 std::string name(m->getDescription());
2202 if(_desc_name!=name)
2204 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2205 oss << name << "' ! Names must match !";
2206 throw INTERP_KERNEL::Exception(oss.str().c_str());
2212 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2214 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2215 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2217 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2218 oss << " - Groups lying on this family : ";
2219 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2220 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2221 oss << std::endl << std::endl;
2226 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2227 * file. The mesh to load is specified by its name and numbers of a time step and an
2229 * \param [in] fileName - the name of MED file to read.
2230 * \param [in] mName - the name of the mesh to read.
2231 * \param [in] dt - the number of a time step.
2232 * \param [in] it - the number of an iteration.
2233 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2234 * mesh using decrRef() as it is no more needed.
2235 * \throw If the file is not readable.
2236 * \throw If there is no mesh with given attributes in the file.
2237 * \throw If the mesh in the file is not an unstructured one.
2239 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2241 MEDFileUtilities::CheckFileForRead(fileName);
2242 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2243 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2247 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2248 * file. The first mesh in the file is loaded.
2249 * \param [in] fileName - the name of MED file to read.
2250 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2251 * mesh using decrRef() as it is no more needed.
2252 * \throw If the file is not readable.
2253 * \throw If there is no meshes in the file.
2254 * \throw If the mesh in the file is not an unstructured one.
2256 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2258 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2261 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2262 throw INTERP_KERNEL::Exception(oss.str().c_str());
2264 MEDFileUtilities::CheckFileForRead(fileName);
2265 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2267 MEDCoupling::MEDCouplingMeshType meshType;
2269 MEDCoupling::MEDCouplingAxisType dummy3;
2270 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2271 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2275 * Returns an empty instance of MEDFileUMesh.
2276 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2277 * mesh using decrRef() as it is no more needed.
2279 MEDFileUMesh *MEDFileUMesh::New()
2281 return new MEDFileUMesh;
2285 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2286 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2287 * \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.
2288 * 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
2289 * at most the memory consumtion.
2291 * \param [in] fileName - the name of the file.
2292 * \param [in] mName - the name of the mesh to be read.
2293 * \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.
2294 * \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.
2295 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2296 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2297 * \param [in] mrs - the request for what to be loaded.
2298 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2300 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)
2302 MEDFileUtilities::CheckFileForRead(fileName);
2303 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2304 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2308 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2309 * This method is \b NOT wrapped into python.
2311 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)
2313 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2314 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2318 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2320 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2321 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2325 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2327 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2328 ret.push_back((const DataArrayDouble*)_coords);
2329 ret.push_back((const DataArrayInt *)_fam_coords);
2330 ret.push_back((const DataArrayInt *)_num_coords);
2331 ret.push_back((const DataArrayInt *)_rev_num_coords);
2332 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2333 ret.push_back((const PartDefinition *)_part_coords);
2334 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2335 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2339 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2341 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2345 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2347 return new MEDFileUMesh;
2350 MEDFileMesh *MEDFileUMesh::deepCpy() const
2352 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2353 ret->deepCpyEquivalences(*this);
2354 if((const DataArrayDouble*)_coords)
2355 ret->_coords=_coords->deepCpy();
2356 if((const DataArrayInt*)_fam_coords)
2357 ret->_fam_coords=_fam_coords->deepCpy();
2358 if((const DataArrayInt*)_num_coords)
2359 ret->_num_coords=_num_coords->deepCpy();
2360 if((const DataArrayInt*)_rev_num_coords)
2361 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2362 if((const DataArrayAsciiChar*)_name_coords)
2363 ret->_name_coords=_name_coords->deepCpy();
2365 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2367 if((const MEDFileUMeshSplitL1 *)(*it))
2368 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2370 if((const PartDefinition*)_part_coords)
2371 ret->_part_coords=_part_coords->deepCpy();
2376 * Checks if \a this and another mesh are equal.
2377 * \param [in] other - the mesh to compare with.
2378 * \param [in] eps - a precision used to compare real values.
2379 * \param [in,out] what - the string returning description of unequal data.
2380 * \return bool - \c true if the meshes are equal, \c false, else.
2382 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2384 if(!MEDFileMesh::isEqual(other,eps,what))
2386 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2389 what="Mesh types differ ! This is unstructured and other is NOT !";
2392 clearNonDiscrAttributes();
2393 otherC->clearNonDiscrAttributes();
2394 const DataArrayDouble *coo1=_coords;
2395 const DataArrayDouble *coo2=otherC->_coords;
2396 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2398 what="Mismatch of coordinates ! One is defined and not other !";
2403 bool ret=coo1->isEqual(*coo2,eps);
2406 what="Coords differ !";
2410 const DataArrayInt *famc1=_fam_coords;
2411 const DataArrayInt *famc2=otherC->_fam_coords;
2412 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2414 what="Mismatch of families arr on nodes ! One is defined and not other !";
2419 bool ret=famc1->isEqual(*famc2);
2422 what="Families arr on node differ !";
2426 const DataArrayInt *numc1=_num_coords;
2427 const DataArrayInt *numc2=otherC->_num_coords;
2428 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2430 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2435 bool ret=numc1->isEqual(*numc2);
2438 what="Numbering arr on node differ !";
2442 const DataArrayAsciiChar *namec1=_name_coords;
2443 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2444 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2446 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2451 bool ret=namec1->isEqual(*namec2);
2454 what="Names arr on node differ !";
2458 if(_ms.size()!=otherC->_ms.size())
2460 what="Number of levels differs !";
2463 std::size_t sz=_ms.size();
2464 for(std::size_t i=0;i<sz;i++)
2466 const MEDFileUMeshSplitL1 *s1=_ms[i];
2467 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2468 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2470 what="Mismatch of presence of sub levels !";
2475 bool ret=s1->isEqual(s2,eps,what);
2480 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2483 if((!pd0 && pd1) || (pd0 && !pd1))
2485 what=std::string("node part def is defined only for one among this or other !");
2488 return pd0->isEqual(pd1,what);
2492 * Clears redundant attributes of incorporated data arrays.
2494 void MEDFileUMesh::clearNonDiscrAttributes() const
2496 MEDFileMesh::clearNonDiscrAttributes();
2497 const DataArrayDouble *coo1=_coords;
2499 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2500 const DataArrayInt *famc1=_fam_coords;
2502 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2503 const DataArrayInt *numc1=_num_coords;
2505 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2506 const DataArrayAsciiChar *namc1=_name_coords;
2508 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2509 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2511 const MEDFileUMeshSplitL1 *tmp=(*it);
2513 tmp->clearNonDiscrAttributes();
2517 void MEDFileUMesh::setName(const std::string& name)
2519 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2520 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2521 (*it)->setName(name);
2522 MEDFileMesh::setName(name);
2525 MEDFileUMesh::MEDFileUMesh()
2529 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2532 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2534 catch(INTERP_KERNEL::Exception& e)
2540 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2541 * See MEDFileUMesh::LoadPartOf for detailed description.
2545 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)
2547 MEDFileUMeshL2 loaderl2;
2548 MEDCoupling::MEDCouplingMeshType meshType;
2551 MEDCoupling::MEDCouplingAxisType dummy3;
2552 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2553 if(meshType!=UNSTRUCTURED)
2555 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2556 throw INTERP_KERNEL::Exception(oss.str().c_str());
2558 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2559 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2563 * \brief Write joints in a file
2565 void MEDFileMesh::writeJoints(med_idt fid) const
2567 if ( (const MEDFileJoints*) _joints )
2568 _joints->write(fid);
2572 * \brief Load joints in a file or use provided ones
2574 //================================================================================
2576 * \brief Load joints in a file or use provided ones
2577 * \param [in] fid - MED file descriptor
2578 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2579 * Usually this joints are those just read by another iteration
2580 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2582 //================================================================================
2584 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2586 if ( toUseInstedOfReading )
2587 setJoints( toUseInstedOfReading );
2589 _joints = MEDFileJoints::New( fid, _name );
2592 void MEDFileMesh::loadEquivalences(med_idt fid)
2594 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2596 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2599 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2601 const MEDFileEquivalences *equiv(other._equiv);
2603 _equiv=equiv->deepCpy(this);
2606 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2608 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2609 if(!thisEq && !otherEq)
2611 if(thisEq && otherEq)
2612 return thisEq->isEqual(otherEq,what);
2615 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2620 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2622 const MEDFileEquivalences *equiv(_equiv);
2625 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2626 _equiv->getRepr(oss);
2629 void MEDFileMesh::checkCartesian() const
2631 if(getAxType()!=AX_CART)
2633 std::ostringstream oss; oss << "MEDFileMesh::checkCartesian : request for method that is dedicated to a cartesian convention ! But you are not in cartesian convention (" << DataArray::GetAxTypeRepr(getAxType()) << ").";
2634 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2635 oss << " - call setAxType(AX_CART)" << std::endl;
2636 oss << " - call cartesianize()";
2637 throw INTERP_KERNEL::Exception(oss.str().c_str());
2642 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2644 int MEDFileMesh::getNumberOfJoints() const
2646 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2650 * \brief Return joints with all adjacent mesh domains
2652 MEDFileJoints * MEDFileMesh::getJoints() const
2654 return const_cast<MEDFileJoints*>(& (*_joints));
2657 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2659 if ( joints != _joints )
2668 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2670 * \sa loadPartUMeshFromFile
2672 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2674 MEDFileUMeshL2 loaderl2;
2675 MEDCoupling::MEDCouplingMeshType meshType;
2678 MEDCoupling::MEDCouplingAxisType axType;
2679 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2681 if(meshType!=UNSTRUCTURED)
2683 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2684 throw INTERP_KERNEL::Exception(oss.str().c_str());
2686 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2687 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2690 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2692 int lev=loaderl2.getNumberOfLevels();
2694 for(int i=0;i<lev;i++)
2696 if(!loaderl2.emptyLev(i))
2697 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2701 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2703 setName(loaderl2.getName());
2704 setDescription(loaderl2.getDescription());
2705 setUnivName(loaderl2.getUnivName());
2706 setIteration(loaderl2.getIteration());
2707 setOrder(loaderl2.getOrder());
2708 setTimeValue(loaderl2.getTime());
2709 setTimeUnit(loaderl2.getTimeUnit());
2710 _coords=loaderl2.getCoords();
2711 if(!mrs || mrs->isNodeFamilyFieldReading())
2712 _fam_coords=loaderl2.getCoordsFamily();
2713 if(!mrs || mrs->isNodeNumFieldReading())
2714 _num_coords=loaderl2.getCoordsNum();
2715 if(!mrs || mrs->isNodeNameFieldReading())
2716 _name_coords=loaderl2.getCoordsName();
2717 _part_coords=loaderl2.getPartDefOfCoo();
2721 MEDFileUMesh::~MEDFileUMesh()
2725 void MEDFileUMesh::writeLL(med_idt fid) const
2727 const DataArrayDouble *coo=_coords;
2728 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2729 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2730 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2731 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2732 int spaceDim=coo?coo->getNumberOfComponents():0;
2735 mdim=getMeshDimension();
2736 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2737 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2738 for(int i=0;i<spaceDim;i++)
2740 std::string info=coo->getInfoOnComponent(i);
2742 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2743 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
2744 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
2746 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),comp,unit));
2748 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2749 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2750 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2751 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2752 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2753 (*it)->write(fid,meshName,mdim);
2754 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2758 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2759 * \return std::vector<int> - a sequence of the relative dimensions.
2761 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2763 std::vector<int> ret;
2765 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2766 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2773 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2774 * \return std::vector<int> - a sequence of the relative dimensions.
2776 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2778 std::vector<int> ret0=getNonEmptyLevels();
2779 if((const DataArrayDouble *) _coords)
2781 std::vector<int> ret(ret0.size()+1);
2783 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2789 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2791 std::vector<int> ret;
2792 const DataArrayInt *famCoo(_fam_coords);
2796 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2798 const MEDFileUMeshSplitL1 *cur(*it);
2800 if(cur->getFamilyField())
2806 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2808 std::vector<int> ret;
2809 const DataArrayInt *numCoo(_num_coords);
2813 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2815 const MEDFileUMeshSplitL1 *cur(*it);
2817 if(cur->getNumberField())
2823 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2825 std::vector<int> ret;
2826 const DataArrayAsciiChar *nameCoo(_name_coords);
2830 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2832 const MEDFileUMeshSplitL1 *cur(*it);
2834 if(cur->getNameField())
2841 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2842 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2843 * \param [in] fams - the name of the family of interest.
2844 * \return std::vector<int> - a sequence of the relative dimensions.
2846 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2848 std::vector<int> ret;
2849 std::vector<int> levs(getNonEmptyLevels());
2850 std::vector<int> famIds(getFamiliesIds(fams));
2851 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2852 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2858 * Returns all relative mesh levels (including nodes) where given families are defined.
2859 * \param [in] fams - the names of the families of interest.
2860 * \return std::vector<int> - a sequence of the relative dimensions.
2862 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2864 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2865 const DataArrayInt *famCoords(_fam_coords);
2868 std::vector<int> famIds(getFamiliesIds(fams));
2869 if(famCoords->presenceOfValue(famIds))
2871 std::vector<int> ret(ret0.size()+1);
2873 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2880 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2882 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2883 if((const DataArrayInt *)_fam_coords)
2885 int val=_fam_coords->getMaxValue(tmp);
2886 ret=std::max(ret,std::abs(val));
2888 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2890 if((const MEDFileUMeshSplitL1 *)(*it))
2892 const DataArrayInt *da=(*it)->getFamilyField();
2895 int val=da->getMaxValue(tmp);
2896 ret=std::max(ret,std::abs(val));
2903 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2905 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2906 if((const DataArrayInt *)_fam_coords)
2908 int val=_fam_coords->getMaxValue(tmp);
2909 ret=std::max(ret,val);
2911 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2913 if((const MEDFileUMeshSplitL1 *)(*it))
2915 const DataArrayInt *da=(*it)->getFamilyField();
2918 int val=da->getMaxValue(tmp);
2919 ret=std::max(ret,val);
2926 int MEDFileUMesh::getMinFamilyIdInArrays() const
2928 int ret=std::numeric_limits<int>::max(),tmp=-1;
2929 if((const DataArrayInt *)_fam_coords)
2931 int val=_fam_coords->getMinValue(tmp);
2932 ret=std::min(ret,val);
2934 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2936 if((const MEDFileUMeshSplitL1 *)(*it))
2938 const DataArrayInt *da=(*it)->getFamilyField();
2941 int val=da->getMinValue(tmp);
2942 ret=std::min(ret,val);
2950 * Returns the dimension on cells in \a this mesh.
2951 * \return int - the mesh dimension.
2952 * \throw If there are no cells in this mesh.
2954 int MEDFileUMesh::getMeshDimension() const
2957 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2958 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2959 return (*it)->getMeshDimension()+lev;
2960 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2964 * Returns the space dimension of \a this mesh that is equal to number of components in
2965 * the node coordinates array.
2966 * \return int - the space dimension of \a this mesh.
2967 * \throw If the node coordinates array is not available.
2969 int MEDFileUMesh::getSpaceDimension() const
2971 const DataArrayDouble *coo=_coords;
2973 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2974 return coo->getNumberOfComponents();
2978 * Returns a string describing \a this mesh.
2979 * \return std::string - the mesh information string.
2981 std::string MEDFileUMesh::simpleRepr() const
2983 std::ostringstream oss;
2984 oss << MEDFileMesh::simpleRepr();
2985 const DataArrayDouble *coo=_coords;
2986 oss << "- The dimension of the space is ";
2987 static const char MSG1[]= "*** NO COORDS SET ***";
2988 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2990 oss << _coords->getNumberOfComponents() << std::endl;
2992 oss << MSG1 << std::endl;
2993 oss << "- Type of the mesh : UNSTRUCTURED\n";
2994 oss << "- Number of nodes : ";
2996 oss << _coords->getNumberOfTuples() << std::endl;
2998 oss << MSG1 << std::endl;
2999 std::size_t nbOfLev=_ms.size();
3000 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3001 for(std::size_t i=0;i<nbOfLev;i++)
3003 const MEDFileUMeshSplitL1 *lev=_ms[i];
3004 oss << " - Level #" << -((int) i) << " has dimension : ";
3007 oss << lev->getMeshDimension() << std::endl;
3008 lev->simpleRepr(oss);
3011 oss << MSG2 << std::endl;
3013 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3016 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3017 oss << "- Names of coordinates :" << std::endl;
3018 std::vector<std::string> vars=coo->getVarsOnComponent();
3019 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3020 oss << std::endl << "- Units of coordinates : " << std::endl;
3021 std::vector<std::string> units=coo->getUnitsOnComponent();
3022 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3024 oss << std::endl << std::endl;
3026 getEquivalencesRepr(oss);
3031 * Returns a full textual description of \a this mesh.
3032 * \return std::string - the string holding the mesh description.
3034 std::string MEDFileUMesh::advancedRepr() const
3036 return simpleRepr();
3040 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3041 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3042 * \return int - the number of entities.
3043 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3045 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3047 if(meshDimRelToMaxExt==1)
3049 if(!((const DataArrayDouble *)_coords))
3050 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3051 return _coords->getNumberOfTuples();
3053 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3057 * Returns the family field for mesh entities of a given dimension.
3058 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3059 * \return const DataArrayInt * - the family field. It is an array of ids of families
3060 * each mesh entity belongs to. It can be \c NULL.
3062 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3064 if(meshDimRelToMaxExt==1)
3066 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3067 return l1->getFamilyField();
3070 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3072 if(meshDimRelToMaxExt==1)
3074 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3075 return l1->getFamilyField();
3079 * Returns the optional numbers of mesh entities of a given dimension.
3080 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3081 * \return const DataArrayInt * - the array of the entity numbers.
3082 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3084 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3086 if(meshDimRelToMaxExt==1)
3088 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3089 return l1->getNumberField();
3092 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3094 if(meshDimRelToMaxExt==1)
3095 return _name_coords;
3096 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3097 return l1->getNameField();
3101 * 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).
3103 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3104 * \param [in] gt - The input geometric type for which the part definition is requested.
3105 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3107 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3109 if(meshDimRelToMaxExt==1)
3110 return _part_coords;
3111 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3112 return l1->getPartDef(gt);
3115 int MEDFileUMesh::getNumberOfNodes() const
3117 const DataArrayDouble *coo(_coords);
3119 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3120 return coo->getNumberOfTuples();
3123 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3125 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3126 return l1->getNumberOfCells();
3129 bool MEDFileUMesh::hasImplicitPart() const
3134 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3136 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3139 void MEDFileUMesh::releaseImplicitPartIfAny() const
3143 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3145 std::size_t sz(st.getNumberOfItems());
3146 for(std::size_t i=0;i<sz;i++)
3148 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3149 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3150 if(st[i].getPflName().empty())
3151 m->computeNodeIdsAlg(nodesFetched);
3154 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3155 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3156 m2->computeNodeIdsAlg(nodesFetched);
3161 MEDFileMesh *MEDFileUMesh::cartesianize() const
3163 if(getAxType()==AX_CART)
3166 return const_cast<MEDFileUMesh *>(this);
3170 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3171 const DataArrayDouble *coords(_coords);
3173 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3174 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsCart(_coords->cartesianize(getAxType()));
3175 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3176 if((const MEDFileUMeshSplitL1 *)(*it))
3177 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3178 ret->_coords=coordsCart;
3179 ret->setAxType(AX_CART);
3185 * Returns the optional numbers of mesh entities of a given dimension transformed using
3186 * DataArrayInt::invertArrayN2O2O2N().
3187 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3188 * \return const DataArrayInt * - the array of the entity numbers transformed using
3189 * DataArrayInt::invertArrayN2O2O2N().
3190 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3192 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3194 if(meshDimRelToMaxExt==1)
3196 if(!((const DataArrayInt *)_num_coords))
3197 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3198 return _rev_num_coords;
3200 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3201 return l1->getRevNumberField();
3205 * Returns a pointer to the node coordinates array of \a this mesh \b without
3206 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3208 DataArrayDouble *MEDFileUMesh::getCoords() const
3211 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
3212 if((DataArrayDouble *)tmp)
3220 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3221 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3223 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3224 * \param [in] grp - the name of the group whose mesh entities are included in the
3226 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3227 * according to the optional numbers of entities, if available.
3228 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3229 * delete this mesh using decrRef() as it is no more needed.
3230 * \throw If the name of a nonexistent group is specified.
3231 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3233 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3236 synchronizeTinyInfoOnLeaves();
3237 std::vector<std::string> tmp(1);
3239 return getGroups(meshDimRelToMaxExt,tmp,renum);
3243 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3244 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3246 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3247 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3249 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3250 * according to the optional numbers of entities, if available.
3251 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3252 * delete this mesh using decrRef() as it is no more needed.
3253 * \throw If a name of a nonexistent group is present in \a grps.
3254 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3256 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3259 synchronizeTinyInfoOnLeaves();
3260 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3261 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3262 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3263 zeRet->setName(grps[0]);
3264 return zeRet.retn();
3268 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3269 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3271 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3272 * \param [in] fam - the name of the family whose mesh entities are included in the
3274 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3275 * according to the optional numbers of entities, if available.
3276 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3277 * delete this mesh using decrRef() as it is no more needed.
3278 * \throw If a name of a nonexistent family is present in \a grps.
3279 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3281 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3284 synchronizeTinyInfoOnLeaves();
3285 std::vector<std::string> tmp(1);
3287 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3291 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3292 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3294 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3295 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3297 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3298 * according to the optional numbers of entities, if available.
3299 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3300 * delete this mesh using decrRef() as it is no more needed.
3301 * \throw If a name of a nonexistent family is present in \a fams.
3302 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3304 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3307 synchronizeTinyInfoOnLeaves();
3308 if(meshDimRelToMaxExt==1)
3310 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3311 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3312 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3316 std::vector<int> famIds=getFamiliesIds(fams);
3317 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3318 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3320 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3322 zeRet=l1->getFamilyPart(0,0,renum);
3323 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3324 zeRet->setName(fams[0]);
3325 return zeRet.retn();
3329 * Returns ids of mesh entities contained in given families of a given dimension.
3330 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3332 * \param [in] fams - the names of the families of interest.
3333 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3334 * returned instead of ids.
3335 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3336 * numbers, if available and required, of mesh entities of the families. The caller
3337 * is to delete this array using decrRef() as it is no more needed.
3338 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3340 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3342 std::vector<int> famIds=getFamiliesIds(fams);
3343 if(meshDimRelToMaxExt==1)
3345 if((const DataArrayInt *)_fam_coords)
3347 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3349 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3351 da=_fam_coords->getIdsEqualList(0,0);
3353 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3358 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3360 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3362 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3364 return l1->getFamilyPartArr(0,0,renum);
3368 * Returns a MEDCouplingUMesh of a given relative dimension.
3369 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3370 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3371 * To build a valid MEDCouplingUMesh from the returned one in this case,
3372 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3373 * \param [in] meshDimRelToMax - the relative dimension of interest.
3374 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3375 * optional numbers of mesh entities.
3376 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3377 * delete using decrRef() as it is no more needed.
3378 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3380 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3383 synchronizeTinyInfoOnLeaves();
3384 if(meshDimRelToMaxExt==1)
3388 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3389 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3390 umesh->setCoords(cc);
3391 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3392 umesh->setName(getName());
3396 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3397 return l1->getWholeMesh(renum);
3400 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3402 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3403 return l1->getDistributionOfTypes();
3407 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3408 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3409 * optional numbers of mesh entities.
3410 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3411 * delete using decrRef() as it is no more needed.
3412 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3414 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3416 return getMeshAtLevel(0,renum);
3420 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3421 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3422 * optional numbers of mesh entities.
3423 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3424 * delete using decrRef() as it is no more needed.
3425 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3427 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3429 return getMeshAtLevel(-1,renum);
3433 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3434 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3435 * optional numbers of mesh entities.
3436 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3437 * delete using decrRef() as it is no more needed.
3438 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3440 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3442 return getMeshAtLevel(-2,renum);
3446 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3447 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3448 * optional numbers of mesh entities.
3449 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3450 * delete using decrRef() as it is no more needed.
3451 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3453 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3455 return getMeshAtLevel(-3,renum);
3459 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3460 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3461 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3462 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3464 void MEDFileUMesh::forceComputationOfParts() const
3466 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3468 const MEDFileUMeshSplitL1 *elt(*it);
3470 elt->forceComputationOfParts();
3475 * This method returns a vector of mesh parts containing each exactly one geometric type.
3476 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3477 * This method is only for memory aware users.
3478 * The returned pointers are **NOT** new object pointer. No need to mange them.
3480 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3483 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3484 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3488 * This method returns the part of \a this having the geometric type \a gt.
3489 * If such part is not existing an exception will be thrown.
3490 * The returned pointer is **NOT** new object pointer. No need to mange it.
3492 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->isIdentity2(o2nCellsPart2->getNumberOfTuples()))
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
3967 if(getMeshDimension()!=2)
3968 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3969 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3970 m1D->checkCoherency();
3971 if(m1D->getMeshDimension()!=1)
3972 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3973 int nbRep(m1D->getNumberOfCells());
3974 std::vector<int> levs(getNonEmptyLevels());
3975 std::vector<std::string> grps(getGroupsNames());
3976 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3977 DataArrayDouble *coords(0);
3978 std::size_t nbOfLevsOut(levs.size()+1);
3979 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3980 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3982 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3983 item=item->clone(false);
3984 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3985 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3986 tmp->changeSpaceDimension(3+(*lev),0.);
3987 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3988 zeList.push_back(elt);
3990 coords=elt->getCoords();
3993 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3994 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3996 (*it)->setName(getName());
3997 (*it)->setCoords(coords);
3999 for(std::size_t ii=0;ii!=zeList.size();ii++)
4002 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
4005 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4006 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
4007 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
4008 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4009 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4010 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4011 std::vector<const MEDCouplingUMesh *> elts(3);
4012 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4013 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4014 elt->setName(getName());
4017 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4018 ret->setMeshAtLevel(lev,elt);
4020 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4021 endLev=endLev->clone(false); endLev->setCoords(coords);
4022 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
4023 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4024 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4025 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4026 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4027 endLev->setName(getName());
4028 ret->setMeshAtLevel(levs.back()-1,endLev);
4030 for(std::size_t ii=0;ii!=zeList.size();ii++)
4033 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
4034 std::vector< const DataArrayInt * > outGrps2;
4037 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4039 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4040 if(!grpArr->empty())
4042 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
4043 int offset0(zeList[ii]->getNumberOfCells());
4044 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4045 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4046 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4047 grpArr2->setName(oss.str());
4048 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4049 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4050 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4051 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4056 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4058 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4059 if(!grpArr->empty())
4061 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4062 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
4063 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4064 for(int iii=0;iii<nbRep;iii++)
4066 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4067 grpArrs2[iii]=grpArrs[iii];
4069 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4070 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4071 std::ostringstream grpName; grpName << *grp << "_extruded";
4072 grpArrExt->setName(grpName.str());
4073 outGrps.push_back(grpArrExt);
4074 outGrps2.push_back(grpArrExt);
4077 ret->setGroupsAtLevel(lev,outGrps2);
4079 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
4080 std::vector< const DataArrayInt * > outGrps2;
4081 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4083 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4084 if(grpArr1->empty())
4086 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
4087 std::ostringstream grpName; grpName << *grp << "_top";
4088 grpArr2->setName(grpName.str());
4089 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4090 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4091 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4093 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4098 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4099 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4100 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4102 * \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
4103 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4104 * \param [in] eps - detection threshold for coordinates.
4105 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4107 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4109 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4112 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4113 int initialNbNodes(getNumberOfNodes());
4114 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4115 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4117 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4119 DataArrayDouble *zeCoords(m0->getCoords());
4120 ret->setMeshAtLevel(0,m0);
4121 std::vector<int> levs(getNonEmptyLevels());
4122 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4125 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4126 ret->setFamilyFieldArr(0,famFieldCpy);
4128 famField=getFamilyFieldAtLevel(1);
4131 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4132 fam->fillWithZero();
4133 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4134 ret->setFamilyFieldArr(1,fam);
4136 ret->copyFamGrpMapsFrom(*this);
4137 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4138 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4142 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4143 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4144 if(m1->getMeshDimension()!=0)
4147 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4148 }//kill unused notUsed var
4149 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
4151 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4152 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4155 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4156 throw INTERP_KERNEL::Exception(oss.str().c_str());
4158 b->applyLin(1,initialNbNodes);
4159 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4160 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4161 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4162 m1->renumberNodesInConn(renum->begin());
4164 m1->setCoords(zeCoords);
4165 ret->setMeshAtLevel(*lev,m1);
4166 famField=getFamilyFieldAtLevel(*lev);
4169 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4170 ret->setFamilyFieldArr(*lev,famFieldCpy);
4177 * This method converts all quadratic cells in \a this into linear cells.
4178 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4179 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4181 * \param [in] eps - detection threshold for coordinates.
4182 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4184 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4186 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4189 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4190 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4191 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4192 m0->convertQuadraticCellsToLinear();
4194 DataArrayDouble *zeCoords(m0->getCoords());
4195 ret->setMeshAtLevel(0,m0);
4196 std::vector<int> levs(getNonEmptyLevels());
4197 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4200 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4201 ret->setFamilyFieldArr(0,famFieldCpy);
4203 famField=getFamilyFieldAtLevel(1);
4206 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
4207 ret->setFamilyFieldArr(1,fam);
4209 ret->copyFamGrpMapsFrom(*this);
4210 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4214 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4215 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4216 m1->convertQuadraticCellsToLinear();
4219 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4220 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4223 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4224 throw INTERP_KERNEL::Exception(oss.str().c_str());
4226 m1->renumberNodesInConn(b->begin());
4227 m1->setCoords(zeCoords);
4228 ret->setMeshAtLevel(*lev,m1);
4229 famField=getFamilyFieldAtLevel(*lev);
4232 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4233 ret->setFamilyFieldArr(*lev,famFieldCpy);
4239 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4241 clearNonDiscrAttributes();
4242 forceComputationOfParts();
4243 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4244 std::vector<int> layer0;
4245 layer0.push_back(getAxType());//0 i
4246 layer0.push_back(_order); //1 i
4247 layer0.push_back(_iteration);//2 i
4248 layer0.push_back(getSpaceDimension());//3 i
4249 tinyDouble.push_back(_time);//0 d
4250 tinyStr.push_back(_name);//0 s
4251 tinyStr.push_back(_desc_name);//1 s
4252 for(int i=0;i<getSpaceDimension();i++)
4253 tinyStr.push_back(_coords->getInfoOnComponent(i));
4254 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4255 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4257 tinyStr.push_back((*it).first);
4258 layer0.push_back((*it).second);
4260 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4261 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4263 layer0.push_back((int)(*it0).second.size());
4264 tinyStr.push_back((*it0).first);
4265 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4266 tinyStr.push_back(*it1);
4268 // sizeof(layer0)==4+aa+1+bb layer#0
4269 bigArrayD=_coords;// 0 bd
4270 bigArraysI.push_back(_fam_coords);// 0 bi
4271 bigArraysI.push_back(_num_coords);// 1 bi
4272 const PartDefinition *pd(_part_coords);
4274 layer0.push_back(-1);
4277 std::vector<int> tmp0;
4278 pd->serialize(tmp0,bigArraysI);
4279 tinyInt.push_back(tmp0.size());
4280 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4283 std::vector<int> layer1;
4284 std::vector<int> levs(getNonEmptyLevels());
4285 layer1.push_back((int)levs.size());// 0 i <- key
4286 layer1.insert(layer1.end(),levs.begin(),levs.end());
4287 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4289 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4290 lev->serialize(layer1,bigArraysI);
4292 // put layers all together.
4293 tinyInt.push_back(layer0.size());
4294 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4295 tinyInt.push_back(layer1.size());
4296 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4299 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4300 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4302 int sz0(tinyInt[0]);
4303 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4304 int sz1(tinyInt[sz0+1]);
4305 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4307 std::reverse(layer0.begin(),layer0.end());
4308 std::reverse(layer1.begin(),layer1.end());
4309 std::reverse(tinyDouble.begin(),tinyDouble.end());
4310 std::reverse(tinyStr.begin(),tinyStr.end());
4311 std::reverse(bigArraysI.begin(),bigArraysI.end());
4313 setAxType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4314 _order=layer0.back(); layer0.pop_back();
4315 _iteration=layer0.back(); layer0.pop_back();
4316 int spaceDim(layer0.back()); layer0.pop_back();
4317 _time=tinyDouble.back(); tinyDouble.pop_back();
4318 _name=tinyStr.back(); tinyStr.pop_back();
4319 _desc_name=tinyStr.back(); tinyStr.pop_back();
4320 _coords=bigArrayD; _coords->rearrange(spaceDim);
4321 for(int i=0;i<spaceDim;i++)
4323 _coords->setInfoOnComponent(i,tinyStr.back());
4326 int nbOfFams(layer0.back()); layer0.pop_back();
4328 for(int i=0;i<nbOfFams;i++)
4330 _families[tinyStr.back()]=layer0.back();
4331 tinyStr.pop_back(); layer0.pop_back();
4333 int nbGroups(layer0.back()); layer0.pop_back();
4335 for(int i=0;i<nbGroups;i++)
4337 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4338 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4339 std::vector<std::string> fams(nbOfFamsOnGrp);
4340 for(int j=0;j<nbOfFamsOnGrp;j++)
4342 fams[j]=tinyStr.back(); tinyStr.pop_back();
4344 _groups[grpName]=fams;
4346 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4347 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4349 int isPd(layer0.back()); layer0.pop_back();
4352 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4353 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4354 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4357 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4359 int nbLevs(layer1.back()); layer1.pop_back();
4360 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4362 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4363 _ms.resize(maxLev+1);
4364 for(int i=0;i<nbLevs;i++)
4368 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4373 * Adds a group of nodes to \a this mesh.
4374 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4375 * The ids should be sorted and different each other (MED file norm).
4377 * \warning this method can alter default "FAMILLE_ZERO" family.
4378 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4380 * \throw If the node coordinates array is not set.
4381 * \throw If \a ids == \c NULL.
4382 * \throw If \a ids->getName() == "".
4383 * \throw If \a ids does not respect the MED file norm.
4384 * \throw If a group with name \a ids->getName() already exists.
4386 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4388 const DataArrayDouble *coords(_coords);
4390 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4391 int nbOfNodes(coords->getNumberOfTuples());
4392 if(!((DataArrayInt *)_fam_coords))
4393 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4395 addGroupUnderground(true,ids,_fam_coords);
4399 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4401 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4402 * The ids should be sorted and different each other (MED file norm).
4404 * \warning this method can alter default "FAMILLE_ZERO" family.
4405 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4407 * \throw If the node coordinates array is not set.
4408 * \throw If \a ids == \c NULL.
4409 * \throw If \a ids->getName() == "".
4410 * \throw If \a ids does not respect the MED file norm.
4411 * \throw If a group with name \a ids->getName() already exists.
4413 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4415 std::vector<int> levs(getNonEmptyLevelsExt());
4416 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4418 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4419 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4421 if(meshDimRelToMaxExt==1)
4422 { addNodeGroup(ids); return ; }
4423 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4424 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4425 addGroupUnderground(false,ids,fam);
4429 * Changes a name of a family specified by its id.
4430 * \param [in] id - the id of the family of interest.
4431 * \param [in] newFamName - the new family name.
4432 * \throw If no family with the given \a id exists.
4434 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4436 std::string oldName=getFamilyNameGivenId(id);
4437 _families.erase(oldName);
4438 _families[newFamName]=id;
4442 * Removes a mesh of a given dimension.
4443 * \param [in] meshDimRelToMax - the relative dimension of interest.
4444 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4446 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4448 std::vector<int> levSet=getNonEmptyLevels();
4449 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4450 if(it==levSet.end())
4451 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4452 int pos=(-meshDimRelToMax);
4457 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4458 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4459 * \param [in] m - the new mesh to set.
4460 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4462 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4463 * another node coordinates array.
4464 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4465 * to the existing meshes of other levels of \a this mesh.
4467 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4469 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4470 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4474 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4475 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4476 * \param [in] m - the new mesh to set.
4477 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4478 * writing \a this mesh in a MED file.
4479 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4481 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4482 * another node coordinates array.
4483 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4484 * to the existing meshes of other levels of \a this mesh.
4486 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4488 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4489 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4492 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4494 dealWithTinyInfo(m);
4495 std::vector<int> levSet=getNonEmptyLevels();
4496 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4498 if((DataArrayDouble *)_coords==0)
4500 DataArrayDouble *c=m->getCoords();
4505 if(m->getCoords()!=_coords)
4506 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4507 int sz=(-meshDimRelToMax)+1;
4508 if(sz>=(int)_ms.size())
4510 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4514 return _ms[-meshDimRelToMax];
4518 * This method allows to set at once the content of different levels in \a this.
4519 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4521 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4522 * \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.
4523 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4525 * \throw If \a there is a null pointer in \a ms.
4526 * \sa MEDFileUMesh::setMeshAtLevel
4528 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4532 const MEDCouplingUMesh *mRef=ms[0];
4534 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4535 std::string name(mRef->getName());
4536 const DataArrayDouble *coo(mRef->getCoords());
4539 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4541 const MEDCouplingUMesh *cur(*it);
4543 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4544 if(coo!=cur->getCoords())
4545 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4546 int mdim=cur->getMeshDimension();
4547 zeDim=std::max(zeDim,mdim);
4548 if(s.find(mdim)!=s.end())
4549 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4551 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4553 int mdim=(*it)->getMeshDimension();
4554 setName((*it)->getName());
4555 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4561 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4562 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4563 * The given meshes must share the same node coordinates array.
4564 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4565 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4566 * create in \a this mesh.
4567 * \throw If \a ms is empty.
4568 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4569 * to the existing meshes of other levels of \a this mesh.
4570 * \throw If the meshes in \a ms do not share the same node coordinates array.
4571 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4572 * of the given meshes.
4573 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4574 * \throw If names of some meshes in \a ms are equal.
4575 * \throw If \a ms includes a mesh with an empty name.
4577 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4580 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4581 int sz=(-meshDimRelToMax)+1;
4582 if(sz>=(int)_ms.size())
4584 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4585 DataArrayDouble *coo=checkMultiMesh(ms);
4586 if((DataArrayDouble *)_coords==0)
4592 if((DataArrayDouble *)_coords!=coo)
4593 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4594 std::vector<DataArrayInt *> corr;
4595 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4596 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4597 setMeshAtLevel(meshDimRelToMax,m,renum);
4598 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4599 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4603 * Creates groups at a given level in \a this mesh from a sequence of
4604 * meshes each representing a group.
4605 * The given meshes must share the same node coordinates array.
4606 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4607 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4608 * create in \a this mesh.
4609 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4611 * \throw If \a ms is empty.
4612 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4613 * to the existing meshes of other levels of \a this mesh.
4614 * \throw If the meshes in \a ms do not share the same node coordinates array.
4615 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4616 * of the given meshes.
4617 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4618 * \throw If names of some meshes in \a ms are equal.
4619 * \throw If \a ms includes a mesh with an empty name.
4621 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4624 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4625 int sz=(-meshDimRelToMax)+1;
4626 if(sz>=(int)_ms.size())
4628 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4629 DataArrayDouble *coo=checkMultiMesh(ms);
4630 if((DataArrayDouble *)_coords==0)
4636 if((DataArrayDouble *)_coords!=coo)
4637 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4638 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4639 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4641 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4643 DataArrayInt *arr=0;
4644 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4648 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4649 throw INTERP_KERNEL::Exception(oss.str().c_str());
4652 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4653 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4656 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4658 const DataArrayDouble *ret=ms[0]->getCoords();
4659 int mdim=ms[0]->getMeshDimension();
4660 for(unsigned int i=1;i<ms.size();i++)
4662 ms[i]->checkCoherency();
4663 if(ms[i]->getCoords()!=ret)
4664 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4665 if(ms[i]->getMeshDimension()!=mdim)
4666 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4668 return const_cast<DataArrayDouble *>(ret);
4672 * Sets the family field of a given relative dimension.
4673 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4674 * the family field is set.
4675 * \param [in] famArr - the array of the family field.
4676 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4677 * \throw If \a famArr has an invalid size.
4679 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4681 if(meshDimRelToMaxExt==1)
4688 DataArrayDouble *coo(_coords);
4690 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4691 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4696 if(meshDimRelToMaxExt>1)
4697 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4698 int traducedRk=-meshDimRelToMaxExt;
4699 if(traducedRk>=(int)_ms.size())
4700 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4701 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4702 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4703 return _ms[traducedRk]->setFamilyArr(famArr);
4707 * Sets the optional numbers of mesh entities of a given dimension.
4708 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4709 * \param [in] renumArr - the array of the numbers.
4710 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4711 * \throw If \a renumArr has an invalid size.
4713 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4715 if(meshDimRelToMaxExt==1)
4723 DataArrayDouble *coo(_coords);
4725 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4726 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4727 renumArr->incrRef();
4728 _num_coords=renumArr;
4732 if(meshDimRelToMaxExt>1)
4733 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4734 int traducedRk=-meshDimRelToMaxExt;
4735 if(traducedRk>=(int)_ms.size())
4736 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4737 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4738 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4739 return _ms[traducedRk]->setRenumArr(renumArr);
4743 * Sets the optional names of mesh entities of a given dimension.
4744 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4745 * \param [in] nameArr - the array of the names.
4746 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4747 * \throw If \a nameArr has an invalid size.
4749 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4751 if(meshDimRelToMaxExt==1)
4758 DataArrayDouble *coo(_coords);
4760 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4761 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4763 _name_coords=nameArr;
4766 if(meshDimRelToMaxExt>1)
4767 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4768 int traducedRk=-meshDimRelToMaxExt;
4769 if(traducedRk>=(int)_ms.size())
4770 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4771 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4772 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4773 return _ms[traducedRk]->setNameArr(nameArr);
4776 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4778 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4779 if((const MEDFileUMeshSplitL1 *)(*it))
4780 (*it)->synchronizeTinyInfo(*this);
4784 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4786 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4788 DataArrayInt *arr=_fam_coords;
4790 arr->changeValue(oldId,newId);
4791 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4793 MEDFileUMeshSplitL1 *sp=(*it);
4796 sp->changeFamilyIdArr(oldId,newId);
4801 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4803 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4804 const DataArrayInt *da(_fam_coords);
4806 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4807 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4809 const MEDFileUMeshSplitL1 *elt(*it);
4812 da=elt->getFamilyField();
4814 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4820 void MEDFileUMesh::computeRevNum() const
4822 if((const DataArrayInt *)_num_coords)
4825 int maxValue=_num_coords->getMaxValue(pos);
4826 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4830 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4832 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4835 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4837 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4838 ret.push_back((const DataArrayInt *)_fam_nodes);
4839 ret.push_back((const DataArrayInt *)_num_nodes);
4840 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4841 ret.push_back((const DataArrayInt *)_fam_cells);
4842 ret.push_back((const DataArrayInt *)_num_cells);
4843 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4844 ret.push_back((const DataArrayInt *)_fam_faces);
4845 ret.push_back((const DataArrayInt *)_num_faces);
4846 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4847 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4848 ret.push_back((const DataArrayInt *)_rev_num_cells);
4849 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4853 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4855 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4856 if((const DataArrayInt *)_fam_nodes)
4858 int val=_fam_nodes->getMaxValue(tmp);
4859 ret=std::max(ret,std::abs(val));
4861 if((const DataArrayInt *)_fam_cells)
4863 int val=_fam_cells->getMaxValue(tmp);
4864 ret=std::max(ret,std::abs(val));
4866 if((const DataArrayInt *)_fam_faces)
4868 int val=_fam_faces->getMaxValue(tmp);
4869 ret=std::max(ret,std::abs(val));
4874 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4876 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4877 if((const DataArrayInt *)_fam_nodes)
4879 int val=_fam_nodes->getMaxValue(tmp);
4880 ret=std::max(ret,val);
4882 if((const DataArrayInt *)_fam_cells)
4884 int val=_fam_cells->getMaxValue(tmp);
4885 ret=std::max(ret,val);
4887 if((const DataArrayInt *)_fam_faces)
4889 int val=_fam_faces->getMaxValue(tmp);
4890 ret=std::max(ret,val);
4895 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4897 int ret=std::numeric_limits<int>::max(),tmp=-1;
4898 if((const DataArrayInt *)_fam_nodes)
4900 int val=_fam_nodes->getMinValue(tmp);
4901 ret=std::min(ret,val);
4903 if((const DataArrayInt *)_fam_cells)
4905 int val=_fam_cells->getMinValue(tmp);
4906 ret=std::min(ret,val);
4908 if((const DataArrayInt *)_fam_faces)
4910 int val=_fam_faces->getMinValue(tmp);
4911 ret=std::min(ret,val);
4916 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4918 if(!MEDFileMesh::isEqual(other,eps,what))
4920 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4923 what="Mesh types differ ! This is structured and other is NOT !";
4926 const DataArrayInt *famc1=_fam_nodes;
4927 const DataArrayInt *famc2=otherC->_fam_nodes;
4928 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4930 what="Mismatch of families arr on nodes ! One is defined and not other !";
4935 bool ret=famc1->isEqual(*famc2);
4938 what="Families arr on nodes differ !";
4943 famc2=otherC->_fam_cells;
4944 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4946 what="Mismatch of families arr on cells ! One is defined and not other !";
4951 bool ret=famc1->isEqual(*famc2);
4954 what="Families arr on cells differ !";
4959 famc2=otherC->_fam_faces;
4960 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4962 what="Mismatch of families arr on faces ! One is defined and not other !";
4967 bool ret=famc1->isEqual(*famc2);
4970 what="Families arr on faces differ !";
4975 famc2=otherC->_num_nodes;
4976 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4978 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4983 bool ret=famc1->isEqual(*famc2);
4986 what="Numbering arr on nodes differ !";
4991 famc2=otherC->_num_cells;
4992 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4994 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4999 bool ret=famc1->isEqual(*famc2);
5002 what="Numbering arr on cells differ !";
5007 famc2=otherC->_num_faces;
5008 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5010 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5015 bool ret=famc1->isEqual(*famc2);
5018 what="Numbering arr on faces differ !";
5022 const DataArrayAsciiChar *d1=_names_cells;
5023 const DataArrayAsciiChar *d2=otherC->_names_cells;
5024 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5026 what="Mismatch of naming arr on cells ! One is defined and not other !";
5031 bool ret=d1->isEqual(*d2);
5034 what="Naming arr on cells differ !";
5039 d2=otherC->_names_faces;
5040 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5042 what="Mismatch of naming arr on faces ! One is defined and not other !";
5047 bool ret=d1->isEqual(*d2);
5050 what="Naming arr on faces differ !";
5055 d2=otherC->_names_nodes;
5056 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5058 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5063 bool ret=d1->isEqual(*d2);
5066 what="Naming arr on nodes differ !";
5073 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5075 MEDFileMesh::clearNonDiscrAttributes();
5076 const DataArrayInt *tmp=_fam_nodes;
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("");
5093 (const_cast<DataArrayInt *>(tmp))->setName("");
5097 * Returns ids of mesh entities contained in given families of a given dimension.
5098 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5100 * \param [in] fams - the names of the families of interest.
5101 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5102 * returned instead of ids.
5103 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5104 * numbers, if available and required, of mesh entities of the families. The caller
5105 * is to delete this array using decrRef() as it is no more needed.
5106 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5108 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5110 std::vector<int> famIds(getFamiliesIds(fams));
5111 switch(meshDimRelToMaxExt)
5115 if((const DataArrayInt *)_fam_nodes)
5117 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5119 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5121 da=_fam_nodes->getIdsEqualList(0,0);
5123 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5128 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5133 if((const DataArrayInt *)_fam_cells)
5135 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5137 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5139 da=_fam_cells->getIdsEqualList(0,0);
5141 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5146 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5151 if((const DataArrayInt *)_fam_faces)
5153 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5155 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5157 da=_fam_faces->getIdsEqualList(0,0);
5159 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5164 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5168 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5170 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5174 * Sets the family field of a given relative dimension.
5175 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5176 * the family field is set.
5177 * \param [in] famArr - the array of the family field.
5178 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5179 * \throw If \a famArr has an invalid size.
5180 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5182 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5184 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5186 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5187 switch(meshDimRelToMaxExt)
5191 int nbCells=mesh->getNumberOfCells();
5192 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5198 int nbNodes=mesh->getNumberOfNodes();
5199 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5205 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5206 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5211 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5218 * Sets the optional numbers of mesh entities of a given dimension.
5219 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5220 * \param [in] renumArr - the array of the numbers.
5221 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5222 * \throw If \a renumArr has an invalid size.
5223 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5225 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5227 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5229 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5230 switch(meshDimRelToMaxExt)
5234 int nbCells=mesh->getNumberOfCells();
5235 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5236 _num_cells=renumArr;
5241 int nbNodes=mesh->getNumberOfNodes();
5242 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5243 _num_nodes=renumArr;
5248 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5249 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5250 _num_faces=renumArr;
5254 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5257 renumArr->incrRef();
5261 * Sets the optional names of mesh entities of a given dimension.
5262 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5263 * \param [in] nameArr - the array of the names.
5264 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5265 * \throw If \a nameArr has an invalid size.
5267 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5269 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5271 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5272 switch(meshDimRelToMaxExt)
5276 int nbCells=mesh->getNumberOfCells();
5277 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5278 _names_cells=nameArr;
5283 int nbNodes=mesh->getNumberOfNodes();
5284 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5285 _names_nodes=nameArr;
5290 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5291 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5292 _names_cells=nameArr;
5295 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5302 * Adds a group of nodes to \a this mesh.
5303 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5304 * The ids should be sorted and different each other (MED file norm).
5306 * \warning this method can alter default "FAMILLE_ZERO" family.
5307 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5309 * \throw If the node coordinates array is not set.
5310 * \throw If \a ids == \c NULL.
5311 * \throw If \a ids->getName() == "".
5312 * \throw If \a ids does not respect the MED file norm.
5313 * \throw If a group with name \a ids->getName() already exists.
5315 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5321 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5323 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5324 * The ids should be sorted and different each other (MED file norm).
5326 * \warning this method can alter default "FAMILLE_ZERO" family.
5327 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5329 * \throw If the node coordinates array is not set.
5330 * \throw If \a ids == \c NULL.
5331 * \throw If \a ids->getName() == "".
5332 * \throw If \a ids does not respect the MED file norm.
5333 * \throw If a group with name \a ids->getName() already exists.
5335 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5337 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5338 addGroupUnderground(false,ids,fam);
5343 * Returns the family field for mesh entities of a given dimension.
5344 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5345 * \return const DataArrayInt * - the family field. It is an array of ids of families
5346 * each mesh entity belongs to. It can be \c NULL.
5347 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5349 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5351 switch(meshDimRelToMaxExt)
5360 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5365 * Returns the family field for mesh entities of a given dimension.
5366 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5367 * \return const DataArrayInt * - the family field. It is an array of ids of families
5368 * each mesh entity belongs to. It can be \c NULL.
5369 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5371 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5373 switch(meshDimRelToMaxExt)
5382 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5387 * Returns the optional numbers of mesh entities of a given dimension.
5388 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5389 * \return const DataArrayInt * - the array of the entity numbers.
5390 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5391 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5393 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5395 switch(meshDimRelToMaxExt)
5404 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5409 * Returns the optional numbers of mesh entities of a given dimension transformed using
5410 * DataArrayInt::invertArrayN2O2O2N().
5411 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5412 * \return const DataArrayInt * - the array of the entity numbers transformed using
5413 * DataArrayInt::invertArrayN2O2O2N().
5414 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5415 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5417 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5419 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5420 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5421 if(meshDimRelToMaxExt==0)
5423 if((const DataArrayInt *)_num_cells)
5426 int maxValue=_num_cells->getMaxValue(pos);
5427 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5428 return _rev_num_cells;
5431 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5435 if((const DataArrayInt *)_num_nodes)
5438 int maxValue=_num_nodes->getMaxValue(pos);
5439 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5440 return _rev_num_nodes;
5443 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5447 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5449 switch(meshDimRelToMaxExt)
5452 return _names_cells;
5454 return _names_nodes;
5456 return _names_faces;
5458 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5463 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5464 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5466 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5468 std::vector<int> ret(1);
5473 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5474 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5476 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5478 std::vector<int> ret(2);
5484 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5486 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5488 std::vector<int> ret;
5489 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5500 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5502 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5504 std::vector<int> ret;
5505 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5516 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5518 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5520 std::vector<int> ret;
5521 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5532 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5534 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5536 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5540 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5542 DataArrayInt *arr=_fam_nodes;
5544 arr->changeValue(oldId,newId);
5547 arr->changeValue(oldId,newId);
5550 arr->changeValue(oldId,newId);
5553 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5555 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
5556 const DataArrayInt *da(_fam_nodes);
5558 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5561 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5564 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5568 void MEDFileStructuredMesh::deepCpyAttributes()
5570 if((const DataArrayInt*)_fam_nodes)
5571 _fam_nodes=_fam_nodes->deepCpy();
5572 if((const DataArrayInt*)_num_nodes)
5573 _num_nodes=_num_nodes->deepCpy();
5574 if((const DataArrayAsciiChar*)_names_nodes)
5575 _names_nodes=_names_nodes->deepCpy();
5576 if((const DataArrayInt*)_fam_cells)
5577 _fam_cells=_fam_cells->deepCpy();
5578 if((const DataArrayInt*)_num_cells)
5579 _num_cells=_num_cells->deepCpy();
5580 if((const DataArrayAsciiChar*)_names_cells)
5581 _names_cells=_names_cells->deepCpy();
5582 if((const DataArrayInt*)_fam_faces)
5583 _fam_faces=_fam_faces->deepCpy();
5584 if((const DataArrayInt*)_num_faces)
5585 _num_faces=_num_faces->deepCpy();
5586 if((const DataArrayAsciiChar*)_names_faces)
5587 _names_faces=_names_faces->deepCpy();
5588 if((const DataArrayInt*)_rev_num_nodes)
5589 _rev_num_nodes=_rev_num_nodes->deepCpy();
5590 if((const DataArrayInt*)_rev_num_cells)
5591 _rev_num_cells=_rev_num_cells->deepCpy();
5595 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5597 * \return a pointer to cartesian mesh that need to be managed by the caller.
5598 * \warning the returned pointer has to be managed by the caller.
5602 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5603 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5604 * \param [in] renum - it must be \c false.
5605 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5606 * delete using decrRef() as it is no more needed.
5608 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
5612 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5613 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5614 switch(meshDimRelToMax)
5620 return const_cast<MEDCouplingStructuredMesh *>(m);
5625 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5626 buildMinusOneImplicitPartIfNeeded();
5627 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
5633 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5637 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
5639 std::vector<int> ret;
5640 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
5641 if(famCells && famCells->presenceOfValue(ret))
5643 if(famFaces && famFaces->presenceOfValue(ret))
5648 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
5650 std::vector<int> ret(getFamsNonEmptyLevels(fams));
5651 const DataArrayInt *famNodes(_fam_nodes);
5652 if(famNodes && famNodes->presenceOfValue(ret))
5658 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5659 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5660 * \return int - the number of entities.
5661 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5663 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5665 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5667 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5668 switch(meshDimRelToMaxExt)
5671 return cmesh->getNumberOfCells();
5673 return cmesh->getNumberOfNodes();
5675 return cmesh->getNumberOfCellsOfSubLevelMesh();
5677 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5681 int MEDFileStructuredMesh::getNumberOfNodes() const
5683 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5685 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5686 return cmesh->getNumberOfNodes();
5689 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5691 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5693 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5694 switch(meshDimRelToMaxExt)
5697 return cmesh->getNumberOfCells();
5699 return cmesh->getNumberOfCellsOfSubLevelMesh();
5701 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5705 bool MEDFileStructuredMesh::hasImplicitPart() const
5711 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5713 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5715 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5716 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5719 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5720 if(cm.getReverseExtrudedType()!=gt)
5721 throw INTERP_KERNEL::Exception(MSG);
5722 buildImplicitPart();
5723 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5727 if(gt!=zeFaceMesh->getCellModelEnum())
5728 throw INTERP_KERNEL::Exception(MSG);
5729 return zeFaceMesh->getNumberOfCells();
5733 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5735 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5737 buildImplicitPart();
5740 void MEDFileStructuredMesh::buildImplicitPart() const
5742 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5744 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5745 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5748 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5750 _faces_if_necessary=0;
5754 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5755 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5757 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5759 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5762 return _faces_if_necessary;
5765 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5767 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5769 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5770 switch(meshDimRelToMax)
5774 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5779 int mdim(cmesh->getMeshDimension());
5781 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5782 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5786 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5790 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
5792 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5795 return getNumberOfCellsAtLevel(0);
5798 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5800 if(st.getNumberOfItems()!=1)
5801 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 !");
5802 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5803 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5804 if(getNumberOfNodes()!=(int)nodesFetched.size())
5805 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5806 if(st[0].getPflName().empty())
5808 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5811 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5812 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5813 int sz(nodesFetched.size());
5814 for(const int *work=arr->begin();work!=arr->end();work++)
5816 std::vector<int> conn;
5817 cmesh->getNodeIdsOfCell(*work,conn);
5818 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5819 if(*it>=0 && *it<sz)
5820 nodesFetched[*it]=true;
5822 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5826 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5828 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5832 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5833 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5835 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5836 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5838 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5841 if(!mrs || mrs->isCellFamilyFieldReading())
5843 famCells=DataArrayInt::New();
5844 famCells->alloc(nbOfElt,1);
5845 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
5848 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5851 if(!mrs || mrs->isCellNumFieldReading())
5853 numCells=DataArrayInt::New();
5854 numCells->alloc(nbOfElt,1);
5855 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
5858 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5861 if(!mrs || mrs->isCellNameFieldReading())
5863 namesCells=DataArrayAsciiChar::New();
5864 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5865 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
5866 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5871 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5873 setName(strm->getName());
5874 setDescription(strm->getDescription());
5875 setUnivName(strm->getUnivName());
5876 setIteration(strm->getIteration());
5877 setOrder(strm->getOrder());
5878 setTimeValue(strm->getTime());
5879 setTimeUnit(strm->getTimeUnit());
5880 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5881 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5882 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
5885 if(!mrs || mrs->isNodeFamilyFieldReading())
5887 int nbNodes(getNumberOfNodes());
5889 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5890 _fam_nodes=DataArrayInt::New();
5891 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5892 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...
5893 _fam_nodes->fillWithZero();
5894 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
5897 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5900 if(!mrs || mrs->isNodeNumFieldReading())
5902 _num_nodes=DataArrayInt::New();
5903 _num_nodes->alloc(nbOfElt,1);
5904 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
5907 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5910 if(!mrs || mrs->isNodeNameFieldReading())
5912 _names_nodes=DataArrayAsciiChar::New();
5913 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5914 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
5915 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5918 int meshDim(getStructuredMesh()->getMeshDimension());
5919 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5921 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5924 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5926 int meshDim(getStructuredMesh()->getMeshDimension());
5927 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5929 if((const DataArrayInt *)_fam_cells)
5930 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
5931 if((const DataArrayInt *)_fam_faces)
5932 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
5933 if((const DataArrayInt *)_fam_nodes)
5934 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
5935 if((const DataArrayInt *)_num_cells)
5936 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
5937 if((const DataArrayInt *)_num_faces)
5938 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
5939 if((const DataArrayInt *)_num_nodes)
5940 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
5941 if((const DataArrayAsciiChar *)_names_cells)
5943 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5945 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5946 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5947 throw INTERP_KERNEL::Exception(oss.str().c_str());
5949 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
5951 if((const DataArrayAsciiChar *)_names_faces)
5953 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5955 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5956 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5957 throw INTERP_KERNEL::Exception(oss.str().c_str());
5959 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
5961 if((const DataArrayAsciiChar *)_names_nodes)
5963 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5965 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5966 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5967 throw INTERP_KERNEL::Exception(oss.str().c_str());
5969 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
5972 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5976 * Returns an empty instance of MEDFileCMesh.
5977 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5978 * mesh using decrRef() as it is no more needed.
5980 MEDFileCMesh *MEDFileCMesh::New()
5982 return new MEDFileCMesh;
5986 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5987 * file. The first mesh in the file is loaded.
5988 * \param [in] fileName - the name of MED file to read.
5989 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5990 * mesh using decrRef() as it is no more needed.
5991 * \throw If the file is not readable.
5992 * \throw If there is no meshes in the file.
5993 * \throw If the mesh in the file is not a Cartesian one.
5995 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5997 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6000 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6001 throw INTERP_KERNEL::Exception(oss.str().c_str());
6003 MEDFileUtilities::CheckFileForRead(fileName);
6004 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6006 MEDCoupling::MEDCouplingMeshType meshType;
6008 MEDCoupling::MEDCouplingAxisType dummy3;
6009 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6010 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
6014 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6015 * file. The mesh to load is specified by its name and numbers of a time step and an
6017 * \param [in] fileName - the name of MED file to read.
6018 * \param [in] mName - the name of the mesh to read.
6019 * \param [in] dt - the number of a time step.
6020 * \param [in] it - the number of an iteration.
6021 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6022 * mesh using decrRef() as it is no more needed.
6023 * \throw If the file is not readable.
6024 * \throw If there is no mesh with given attributes in the file.
6025 * \throw If the mesh in the file is not a Cartesian one.
6027 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6029 MEDFileUtilities::CheckFileForRead(fileName);
6030 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6031 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6034 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6036 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6039 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6041 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6042 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6047 * Returns the dimension on cells in \a this mesh.
6048 * \return int - the mesh dimension.
6049 * \throw If there are no cells in this mesh.
6051 int MEDFileCMesh::getMeshDimension() const
6053 if(!((const MEDCouplingCMesh*)_cmesh))
6054 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6055 return _cmesh->getMeshDimension();
6059 * Returns the dimension on nodes in \a this mesh.
6060 * \return int - the space dimension.
6061 * \throw If there are no cells in this mesh.
6063 int MEDFileCMesh::getSpaceDimension() const
6065 if(!((const MEDCouplingCMesh*)_cmesh))
6066 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6067 return _cmesh->getSpaceDimension();
6071 * Returns a string describing \a this mesh.
6072 * \return std::string - the mesh information string.
6074 std::string MEDFileCMesh::simpleRepr() const
6076 return MEDFileStructuredMesh::simpleRepr();
6080 * Returns a full textual description of \a this mesh.
6081 * \return std::string - the string holding the mesh description.
6083 std::string MEDFileCMesh::advancedRepr() const
6085 return simpleRepr();
6088 MEDFileMesh *MEDFileCMesh::shallowCpy() const
6090 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6094 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6096 return new MEDFileCMesh;
6099 MEDFileMesh *MEDFileCMesh::deepCpy() const
6101 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6102 ret->deepCpyEquivalences(*this);
6103 if((const MEDCouplingCMesh*)_cmesh)
6104 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
6105 ret->deepCpyAttributes();
6110 * Checks if \a this and another mesh are equal.
6111 * \param [in] other - the mesh to compare with.
6112 * \param [in] eps - a precision used to compare real values.
6113 * \param [in,out] what - the string returning description of unequal data.
6114 * \return bool - \c true if the meshes are equal, \c false, else.
6116 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6118 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6120 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6123 what="Mesh types differ ! This is cartesian and other is NOT !";
6126 clearNonDiscrAttributes();
6127 otherC->clearNonDiscrAttributes();
6128 const MEDCouplingCMesh *coo1=_cmesh;
6129 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6130 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6132 what="Mismatch of cartesian meshes ! One is defined and not other !";
6137 bool ret=coo1->isEqual(coo2,eps);
6140 what="cartesian meshes differ !";
6148 * Clears redundant attributes of incorporated data arrays.
6150 void MEDFileCMesh::clearNonDiscrAttributes() const
6152 MEDFileStructuredMesh::clearNonDiscrAttributes();
6153 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6156 MEDFileCMesh::MEDFileCMesh()
6160 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6163 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6165 catch(INTERP_KERNEL::Exception& e)
6170 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6172 MEDCoupling::MEDCouplingMeshType meshType;
6175 MEDCoupling::MEDCouplingAxisType axType;
6176 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6177 if(meshType!=CARTESIAN)
6179 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6180 throw INTERP_KERNEL::Exception(oss.str().c_str());
6182 MEDFileCMeshL2 loaderl2;
6183 loaderl2.loadAll(fid,mid,mName,dt,it);
6185 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6188 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6192 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6193 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6195 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6197 synchronizeTinyInfoOnLeaves();
6201 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6203 synchronizeTinyInfoOnLeaves();
6208 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6209 * \param [in] m - the new MEDCouplingCMesh to refer to.
6210 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6213 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6215 dealWithTinyInfo(m);
6221 MEDFileMesh *MEDFileCMesh::cartesianize() const
6223 if(getAxType()==AX_CART)
6226 return const_cast<MEDFileCMesh *>(this);
6230 const MEDCouplingCMesh *cmesh(getMesh());
6232 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6233 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6234 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxType()));
6235 clmesh->setCoords(coords);
6236 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6237 ret->MEDFileStructuredMesh::operator=(*this);
6238 ret->setMesh(clmesh);
6239 ret->setAxType(AX_CART);
6244 void MEDFileCMesh::writeLL(med_idt fid) const
6246 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6247 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6248 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6249 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6250 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6251 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6252 int spaceDim(_cmesh->getSpaceDimension());
6253 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6254 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6255 for(int i=0;i<spaceDim;i++)
6257 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6259 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6260 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
6261 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
6263 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),comp,unit));
6265 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6266 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxType())));
6267 for(int i=0;i<spaceDim;i++)
6269 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6270 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6273 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6274 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6277 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6279 const MEDCouplingCMesh *cmesh=_cmesh;
6282 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6283 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6284 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6285 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6288 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6290 return new MEDFileCurveLinearMesh;
6293 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6295 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6298 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6299 throw INTERP_KERNEL::Exception(oss.str().c_str());
6301 MEDFileUtilities::CheckFileForRead(fileName);
6302 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6304 MEDCoupling::MEDCouplingMeshType meshType;
6305 MEDCoupling::MEDCouplingAxisType dummy3;
6307 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6308 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6311 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6313 MEDFileUtilities::CheckFileForRead(fileName);
6314 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6315 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6318 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6320 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6323 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6325 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6326 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6330 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6332 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6336 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6338 return new MEDFileCurveLinearMesh;
6341 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
6343 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6344 ret->deepCpyEquivalences(*this);
6345 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6346 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
6347 ret->deepCpyAttributes();
6351 int MEDFileCurveLinearMesh::getMeshDimension() const
6353 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6354 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6355 return _clmesh->getMeshDimension();
6358 std::string MEDFileCurveLinearMesh::simpleRepr() const
6360 return MEDFileStructuredMesh::simpleRepr();
6363 std::string MEDFileCurveLinearMesh::advancedRepr() const
6365 return simpleRepr();
6368 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6370 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6372 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6375 what="Mesh types differ ! This is curve linear and other is NOT !";
6378 clearNonDiscrAttributes();
6379 otherC->clearNonDiscrAttributes();
6380 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6381 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6382 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6384 what="Mismatch of curve linear meshes ! One is defined and not other !";
6389 bool ret=coo1->isEqual(coo2,eps);
6392 what="curve linear meshes differ !";
6399 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6401 MEDFileStructuredMesh::clearNonDiscrAttributes();
6402 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6405 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6407 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6410 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6411 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6412 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6413 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6416 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6418 synchronizeTinyInfoOnLeaves();
6422 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6424 dealWithTinyInfo(m);
6430 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6432 if(getAxType()==AX_CART)
6435 return const_cast<MEDFileCurveLinearMesh *>(this);
6439 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6441 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6442 const DataArrayDouble *coords(mesh->getCoords());
6444 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6445 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6446 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6447 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsCart(coords->cartesianize(getAxType()));
6448 mesh2->setCoords(coordsCart);
6449 ret->setMesh(mesh2);
6450 ret->setAxType(AX_CART);
6455 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6457 synchronizeTinyInfoOnLeaves();
6461 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6465 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6468 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6470 catch(INTERP_KERNEL::Exception& e)
6475 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6477 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6478 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6479 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6480 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6481 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6482 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6483 int spaceDim=_clmesh->getSpaceDimension();
6484 int meshDim=_clmesh->getMeshDimension();
6485 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6486 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6487 const DataArrayDouble *coords=_clmesh->getCoords();
6489 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6490 for(int i=0;i<spaceDim;i++)
6492 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6494 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6495 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
6496 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
6498 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxType()),comp,unit));
6500 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6501 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6502 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6503 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6505 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6507 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6508 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6511 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6513 MEDCoupling::MEDCouplingMeshType meshType;
6516 MEDCoupling::MEDCouplingAxisType axType;
6517 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6519 if(meshType!=CURVE_LINEAR)
6521 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6522 throw INTERP_KERNEL::Exception(oss.str().c_str());
6524 MEDFileCLMeshL2 loaderl2;
6525 loaderl2.loadAll(fid,mid,mName,dt,it);
6526 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6529 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6532 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6534 return new MEDFileMeshMultiTS;
6537 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6539 return new MEDFileMeshMultiTS(fileName);
6542 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6544 return new MEDFileMeshMultiTS(fileName,mName);
6547 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6549 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6550 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6552 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6553 if((const MEDFileMesh *)*it)
6554 meshOneTs[i]=(*it)->deepCpy();
6555 ret->_mesh_one_ts=meshOneTs;
6559 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6561 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6564 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6566 std::vector<const BigMemoryObject *> ret;
6567 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6568 ret.push_back((const MEDFileMesh *)*it);
6572 std::string MEDFileMeshMultiTS::getName() const
6574 if(_mesh_one_ts.empty())
6575 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6576 return _mesh_one_ts[0]->getName();
6579 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6581 std::string oldName(getName());
6582 std::vector< std::pair<std::string,std::string> > v(1);
6583 v[0].first=oldName; v[0].second=newMeshName;
6587 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6590 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6592 MEDFileMesh *cur(*it);
6594 ret=cur->changeNames(modifTab) || ret;
6599 void MEDFileMeshMultiTS::cartesianizeMe()
6601 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6603 MEDFileMesh *cur(*it);
6606 MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
6612 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6614 if(_mesh_one_ts.empty())
6615 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6616 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6619 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6622 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6623 _mesh_one_ts.resize(1);
6624 mesh1TimeStep->incrRef();
6625 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6626 _mesh_one_ts[0]=mesh1TimeStep;
6629 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
6631 if ( MEDFileMesh* m = getOneTimeStep() )
6632 return m->getJoints();
6637 * \brief Set Joints that are common to all time-stamps
6639 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
6641 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6643 (*it)->setJoints( joints );
6647 void MEDFileMeshMultiTS::write(med_idt fid) const
6649 MEDFileJoints *joints(getJoints());
6650 bool jointsWritten(false);
6652 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6654 if ( jointsWritten )
6655 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
6657 jointsWritten = true;
6659 (*it)->copyOptionsFrom(*this);
6663 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
6666 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6668 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6669 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6670 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6671 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6675 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6677 MEDFileJoints* joints = 0;
6678 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
6680 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
6681 joints = getOneTimeStep()->getJoints();
6684 _mesh_one_ts.clear(); //for the moment to be improved
6685 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
6688 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6692 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6695 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6698 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6699 throw INTERP_KERNEL::Exception(oss.str().c_str());
6701 MEDFileUtilities::CheckFileForRead(fileName);
6702 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6704 MEDCoupling::MEDCouplingMeshType meshType;
6706 MEDCoupling::MEDCouplingAxisType dummy3;
6707 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6708 loadFromFile(fileName,ms.front());
6710 catch(INTERP_KERNEL::Exception& e)
6715 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6718 loadFromFile(fileName,mName);
6720 catch(INTERP_KERNEL::Exception& e)
6725 MEDFileMeshes *MEDFileMeshes::New()
6727 return new MEDFileMeshes;
6730 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6732 return new MEDFileMeshes(fileName);
6735 void MEDFileMeshes::write(med_idt fid) const
6738 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6740 (*it)->copyOptionsFrom(*this);
6745 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6747 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6748 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6749 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6750 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6755 int MEDFileMeshes::getNumberOfMeshes() const
6757 return _meshes.size();
6760 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6762 return new MEDFileMeshesIterator(this);
6765 /** Return a borrowed reference (caller is not responsible) */
6766 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6768 if(i<0 || i>=(int)_meshes.size())
6770 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6771 throw INTERP_KERNEL::Exception(oss.str().c_str());
6773 return _meshes[i]->getOneTimeStep();
6776 /** Return a borrowed reference (caller is not responsible) */
6777 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6779 std::vector<std::string> ms=getMeshesNames();
6780 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6783 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6784 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6785 throw INTERP_KERNEL::Exception(oss.str().c_str());
6787 return getMeshAtPos((int)std::distance(ms.begin(),it));
6790 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6792 std::vector<std::string> ret(_meshes.size());
6794 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6796 const MEDFileMeshMultiTS *f=(*it);
6799 ret[i]=f->getName();
6803 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6804 throw INTERP_KERNEL::Exception(oss.str().c_str());
6810 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6813 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6815 MEDFileMeshMultiTS *cur(*it);
6817 ret=cur->changeNames(modifTab) || ret;
6822 void MEDFileMeshes::cartesianizeMe()
6824 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6826 MEDFileMeshMultiTS *cur(*it);
6828 cur->cartesianizeMe();
6832 void MEDFileMeshes::resize(int newSize)
6834 _meshes.resize(newSize);
6837 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6840 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6841 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6842 elt->setOneTimeStep(mesh);
6843 _meshes.push_back(elt);
6846 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6849 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6850 if(i>=(int)_meshes.size())
6851 _meshes.resize(i+1);
6852 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6853 elt->setOneTimeStep(mesh);
6857 void MEDFileMeshes::destroyMeshAtPos(int i)
6859 if(i<0 || i>=(int)_meshes.size())
6861 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6862 throw INTERP_KERNEL::Exception(oss.str().c_str());
6864 _meshes.erase(_meshes.begin()+i);
6867 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6869 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6871 _meshes.resize(ms.size());
6872 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6873 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6876 MEDFileMeshes::MEDFileMeshes()
6880 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6883 loadFromFile(fileName);
6885 catch(INTERP_KERNEL::Exception& /*e*/)
6889 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6891 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6893 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6894 if((const MEDFileMeshMultiTS *)*it)
6895 meshes[i]=(*it)->deepCpy();
6896 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6897 ret->_meshes=meshes;
6901 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6903 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6906 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6908 std::vector<const BigMemoryObject *> ret;
6909 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6910 ret.push_back((const MEDFileMeshMultiTS *)*it);
6914 std::string MEDFileMeshes::simpleRepr() const
6916 std::ostringstream oss;
6917 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6918 simpleReprWithoutHeader(oss);
6922 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6924 int nbOfMeshes=getNumberOfMeshes();
6925 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6926 std::vector<std::string> mns=getMeshesNames();
6927 for(int i=0;i<nbOfMeshes;i++)
6928 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6931 void MEDFileMeshes::checkCoherency() const
6933 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6935 std::set<std::string> s;
6936 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6938 const MEDFileMeshMultiTS *elt=(*it);
6941 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6942 throw INTERP_KERNEL::Exception(oss.str().c_str());
6944 std::size_t sz=s.size();
6945 s.insert(std::string((*it)->getName()));
6948 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6949 throw INTERP_KERNEL::Exception(oss.str().c_str());
6954 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6959 _nb_iter=ms->getNumberOfMeshes();
6963 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6967 MEDFileMesh *MEDFileMeshesIterator::nextt()
6969 if(_iter_id<_nb_iter)
6971 MEDFileMeshes *ms(_ms);
6973 return ms->getMeshAtPos(_iter_id++);