1 // Copyright (C) 2007-2016 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=MEDCoupling::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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
833 if(!unfetchedIds->empty())
835 MCAuto<DataArrayInt> newFams(fams->deepCopy());
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 MCAuto<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 MCAuto<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(); MCAuto<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< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1285 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1286 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1287 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1288 std::vector<int> familyIds;
1289 std::vector< MCAuto<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 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1298 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1299 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1300 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1303 bool isFamPresent=false;
1304 for(std::list< MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<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 MCAuto<DataArrayInt> fam;
2032 std::vector< std::vector<int> > fidsOfGroups;
2035 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2039 std::vector< MCAuto<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 MCAuto<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 MCAuto<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(MEDCoupling::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 MCAuto<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(MCAuto<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< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2335 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2339 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2341 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2345 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2347 return new MEDFileUMesh;
2350 MEDFileMesh *MEDFileUMesh::deepCopy() const
2352 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2353 ret->deepCpyEquivalences(*this);
2354 if((const DataArrayDouble*)_coords)
2355 ret->_coords=_coords->deepCopy();
2356 if((const DataArrayInt*)_fam_coords)
2357 ret->_fam_coords=_fam_coords->deepCopy();
2358 if((const DataArrayInt*)_num_coords)
2359 ret->_num_coords=_num_coords->deepCopy();
2360 if((const DataArrayInt*)_rev_num_coords)
2361 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2362 if((const DataArrayAsciiChar*)_name_coords)
2363 ret->_name_coords=_name_coords->deepCopy();
2365 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2367 if((const MEDFileUMeshSplitL1 *)(*it))
2368 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2370 if((const PartDefinition*)_part_coords)
2371 ret->_part_coords=_part_coords->deepCopy();
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 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2493 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2494 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2495 * \throw if internal family array is inconsistent
2496 * \sa checkSMESHConsistency()
2498 void MEDFileUMesh::checkConsistency() const
2500 if(!_coords || !_coords->isAllocated())
2503 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2505 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2506 if (!_num_coords || !_rev_num_coords)
2507 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2511 int nbCoo = _coords->getNumberOfTuples();
2513 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2516 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2518 int maxValue=_num_coords->getMaxValue(pos);
2519 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2520 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2522 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2523 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2524 if (_num_coords && !_num_coords->hasUniqueValues())
2525 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2527 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2528 // Now sub part check:
2529 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2530 it != _ms.end(); it++)
2531 (*it)->checkConsistency();
2536 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2537 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2538 * entities as it likes), or non overlapping between all sub-levels.
2539 * \throw if the condition above is not respected
2541 void MEDFileUMesh::checkSMESHConsistency() const
2544 // For all sub-levels, numbering is either always null or with void intersection:
2547 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2548 std::vector< const DataArrayInt * > v;
2549 bool voidOrNot = ((*it)->_num == 0);
2550 for (it++; it != _ms.end(); it++)
2551 if( ((*it)->_num == 0) != voidOrNot )
2552 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2553 else if (!voidOrNot)
2554 v.push_back((*it)->_num);
2557 // don't forget the 1st one:
2558 v.push_back(_ms[0]->_num);
2559 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2560 if (inter->getNumberOfTuples())
2561 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2567 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2568 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2570 void MEDFileUMesh::clearNodeAndCellNumbers()
2573 _rev_num_coords = 0;
2574 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2575 it != _ms.end(); it++)
2578 (*it)->_rev_num = 0;
2583 * Clears redundant attributes of incorporated data arrays.
2585 void MEDFileUMesh::clearNonDiscrAttributes() const
2587 MEDFileMesh::clearNonDiscrAttributes();
2588 const DataArrayDouble *coo1=_coords;
2590 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2591 const DataArrayInt *famc1=_fam_coords;
2593 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2594 const DataArrayInt *numc1=_num_coords;
2596 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2597 const DataArrayAsciiChar *namc1=_name_coords;
2599 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2600 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2602 const MEDFileUMeshSplitL1 *tmp=(*it);
2604 tmp->clearNonDiscrAttributes();
2608 void MEDFileUMesh::setName(const std::string& name)
2610 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2611 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2612 (*it)->setName(name);
2613 MEDFileMesh::setName(name);
2616 MEDFileUMesh::MEDFileUMesh()
2620 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2623 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2625 catch(INTERP_KERNEL::Exception& e)
2631 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2632 * See MEDFileUMesh::LoadPartOf for detailed description.
2636 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)
2638 MEDFileUMeshL2 loaderl2;
2639 MEDCoupling::MEDCouplingMeshType meshType;
2642 MEDCoupling::MEDCouplingAxisType dummy3;
2643 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2644 if(meshType!=UNSTRUCTURED)
2646 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2647 throw INTERP_KERNEL::Exception(oss.str().c_str());
2649 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2650 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2654 * \brief Write joints in a file
2656 void MEDFileMesh::writeJoints(med_idt fid) const
2658 if ( (const MEDFileJoints*) _joints )
2659 _joints->write(fid);
2663 * \brief Load joints in a file or use provided ones
2665 //================================================================================
2667 * \brief Load joints in a file or use provided ones
2668 * \param [in] fid - MED file descriptor
2669 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2670 * Usually this joints are those just read by another iteration
2671 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2673 //================================================================================
2675 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2677 if ( toUseInstedOfReading )
2678 setJoints( toUseInstedOfReading );
2680 _joints = MEDFileJoints::New( fid, _name );
2683 void MEDFileMesh::loadEquivalences(med_idt fid)
2685 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2687 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2690 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2692 const MEDFileEquivalences *equiv(other._equiv);
2694 _equiv=equiv->deepCopy(this);
2697 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2699 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2700 if(!thisEq && !otherEq)
2702 if(thisEq && otherEq)
2703 return thisEq->isEqual(otherEq,what);
2706 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2711 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2713 const MEDFileEquivalences *equiv(_equiv);
2716 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2717 _equiv->getRepr(oss);
2720 void MEDFileMesh::checkCartesian() const
2722 if(getAxisType()!=AX_CART)
2724 std::ostringstream oss; oss << "MEDFileMesh::checkCartesian : request for method that is dedicated to a cartesian convention ! But you are not in cartesian convention (" << DataArray::GetAxisTypeRepr(getAxisType()) << ").";
2725 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2726 oss << " - call setAxisType(AX_CART)" << std::endl;
2727 oss << " - call cartesianize()";
2728 throw INTERP_KERNEL::Exception(oss.str().c_str());
2733 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2735 int MEDFileMesh::getNumberOfJoints() const
2737 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2741 * \brief Return joints with all adjacent mesh domains
2743 MEDFileJoints * MEDFileMesh::getJoints() const
2745 return const_cast<MEDFileJoints*>(& (*_joints));
2748 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2750 if ( joints != _joints )
2759 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2761 * \sa loadPartUMeshFromFile
2763 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2765 MEDFileUMeshL2 loaderl2;
2766 MEDCoupling::MEDCouplingMeshType meshType;
2769 MEDCoupling::MEDCouplingAxisType axType;
2770 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2771 setAxisType(axType);
2772 if(meshType!=UNSTRUCTURED)
2774 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2775 throw INTERP_KERNEL::Exception(oss.str().c_str());
2777 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2778 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2781 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2783 int lev=loaderl2.getNumberOfLevels();
2785 for(int i=0;i<lev;i++)
2787 if(!loaderl2.emptyLev(i))
2788 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2792 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2794 setName(loaderl2.getName());
2795 setDescription(loaderl2.getDescription());
2796 setUnivName(loaderl2.getUnivName());
2797 setIteration(loaderl2.getIteration());
2798 setOrder(loaderl2.getOrder());
2799 setTimeValue(loaderl2.getTime());
2800 setTimeUnit(loaderl2.getTimeUnit());
2801 _coords=loaderl2.getCoords();
2802 if(!mrs || mrs->isNodeFamilyFieldReading())
2803 _fam_coords=loaderl2.getCoordsFamily();
2804 if(!mrs || mrs->isNodeNumFieldReading())
2805 _num_coords=loaderl2.getCoordsNum();
2806 if(!mrs || mrs->isNodeNameFieldReading())
2807 _name_coords=loaderl2.getCoordsName();
2808 _part_coords=loaderl2.getPartDefOfCoo();
2812 MEDFileUMesh::~MEDFileUMesh()
2816 void MEDFileUMesh::writeLL(med_idt fid) const
2818 const DataArrayDouble *coo=_coords;
2819 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2820 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2821 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2822 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2823 int spaceDim=coo?coo->getNumberOfComponents():0;
2826 mdim=getMeshDimension();
2827 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2828 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2829 for(int i=0;i<spaceDim;i++)
2831 std::string info=coo->getInfoOnComponent(i);
2833 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2834 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
2835 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
2837 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2839 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2840 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2841 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2842 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2843 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2844 (*it)->write(fid,meshName,mdim);
2845 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2849 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2850 * \return std::vector<int> - a sequence of the relative dimensions.
2852 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2854 std::vector<int> ret;
2856 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2857 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2864 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2865 * \return std::vector<int> - a sequence of the relative dimensions.
2867 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2869 std::vector<int> ret0=getNonEmptyLevels();
2870 if((const DataArrayDouble *) _coords)
2872 std::vector<int> ret(ret0.size()+1);
2874 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2880 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2882 std::vector<int> ret;
2883 const DataArrayInt *famCoo(_fam_coords);
2887 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2889 const MEDFileUMeshSplitL1 *cur(*it);
2891 if(cur->getFamilyField())
2897 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2899 std::vector<int> ret;
2900 const DataArrayInt *numCoo(_num_coords);
2904 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2906 const MEDFileUMeshSplitL1 *cur(*it);
2908 if(cur->getNumberField())
2914 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2916 std::vector<int> ret;
2917 const DataArrayAsciiChar *nameCoo(_name_coords);
2921 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2923 const MEDFileUMeshSplitL1 *cur(*it);
2925 if(cur->getNameField())
2932 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2933 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2934 * \param [in] fams - the name of the family of interest.
2935 * \return std::vector<int> - a sequence of the relative dimensions.
2937 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2939 std::vector<int> ret;
2940 std::vector<int> levs(getNonEmptyLevels());
2941 std::vector<int> famIds(getFamiliesIds(fams));
2942 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2943 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2949 * Returns all relative mesh levels (including nodes) where given families are defined.
2950 * \param [in] fams - the names of the families of interest.
2951 * \return std::vector<int> - a sequence of the relative dimensions.
2953 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2955 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2956 const DataArrayInt *famCoords(_fam_coords);
2959 std::vector<int> famIds(getFamiliesIds(fams));
2960 if(famCoords->presenceOfValue(famIds))
2962 std::vector<int> ret(ret0.size()+1);
2964 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2971 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2973 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2974 if((const DataArrayInt *)_fam_coords)
2976 int val=_fam_coords->getMaxValue(tmp);
2977 ret=std::max(ret,std::abs(val));
2979 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2981 if((const MEDFileUMeshSplitL1 *)(*it))
2983 const DataArrayInt *da=(*it)->getFamilyField();
2986 int val=da->getMaxValue(tmp);
2987 ret=std::max(ret,std::abs(val));
2994 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2996 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2997 if((const DataArrayInt *)_fam_coords)
2999 int val=_fam_coords->getMaxValue(tmp);
3000 ret=std::max(ret,val);
3002 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3004 if((const MEDFileUMeshSplitL1 *)(*it))
3006 const DataArrayInt *da=(*it)->getFamilyField();
3009 int val=da->getMaxValue(tmp);
3010 ret=std::max(ret,val);
3017 int MEDFileUMesh::getMinFamilyIdInArrays() const
3019 int ret=std::numeric_limits<int>::max(),tmp=-1;
3020 if((const DataArrayInt *)_fam_coords)
3022 int val=_fam_coords->getMinValue(tmp);
3023 ret=std::min(ret,val);
3025 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3027 if((const MEDFileUMeshSplitL1 *)(*it))
3029 const DataArrayInt *da=(*it)->getFamilyField();
3032 int val=da->getMinValue(tmp);
3033 ret=std::min(ret,val);
3041 * Returns the dimension on cells in \a this mesh.
3042 * \return int - the mesh dimension.
3043 * \throw If there are no cells in this mesh.
3045 int MEDFileUMesh::getMeshDimension() const
3048 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3049 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3050 return (*it)->getMeshDimension()+lev;
3051 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3055 * Returns the space dimension of \a this mesh that is equal to number of components in
3056 * the node coordinates array.
3057 * \return int - the space dimension of \a this mesh.
3058 * \throw If the node coordinates array is not available.
3060 int MEDFileUMesh::getSpaceDimension() const
3062 const DataArrayDouble *coo=_coords;
3064 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3065 return coo->getNumberOfComponents();
3069 * Returns a string describing \a this mesh.
3070 * \return std::string - the mesh information string.
3072 std::string MEDFileUMesh::simpleRepr() const
3074 std::ostringstream oss;
3075 oss << MEDFileMesh::simpleRepr();
3076 const DataArrayDouble *coo=_coords;
3077 oss << "- The dimension of the space is ";
3078 static const char MSG1[]= "*** NO COORDS SET ***";
3079 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3081 oss << _coords->getNumberOfComponents() << std::endl;
3083 oss << MSG1 << std::endl;
3084 oss << "- Type of the mesh : UNSTRUCTURED\n";
3085 oss << "- Number of nodes : ";
3087 oss << _coords->getNumberOfTuples() << std::endl;
3089 oss << MSG1 << std::endl;
3090 std::size_t nbOfLev=_ms.size();
3091 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3092 for(std::size_t i=0;i<nbOfLev;i++)
3094 const MEDFileUMeshSplitL1 *lev=_ms[i];
3095 oss << " - Level #" << -((int) i) << " has dimension : ";
3098 oss << lev->getMeshDimension() << std::endl;
3099 lev->simpleRepr(oss);
3102 oss << MSG2 << std::endl;
3104 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3107 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3108 oss << "- Names of coordinates :" << std::endl;
3109 std::vector<std::string> vars=coo->getVarsOnComponent();
3110 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3111 oss << std::endl << "- Units of coordinates : " << std::endl;
3112 std::vector<std::string> units=coo->getUnitsOnComponent();
3113 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3115 oss << std::endl << std::endl;
3117 getEquivalencesRepr(oss);
3122 * Returns a full textual description of \a this mesh.
3123 * \return std::string - the string holding the mesh description.
3125 std::string MEDFileUMesh::advancedRepr() const
3127 return simpleRepr();
3131 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3132 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3133 * \return int - the number of entities.
3134 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3136 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3138 if(meshDimRelToMaxExt==1)
3140 if(!((const DataArrayDouble *)_coords))
3141 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3142 return _coords->getNumberOfTuples();
3144 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3148 * Returns the family field for mesh entities of a given dimension.
3149 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3150 * \return const DataArrayInt * - the family field. It is an array of ids of families
3151 * each mesh entity belongs to. It can be \c NULL.
3153 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3155 if(meshDimRelToMaxExt==1)
3157 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3158 return l1->getFamilyField();
3161 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3163 if(meshDimRelToMaxExt==1)
3165 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3166 return l1->getFamilyField();
3170 * Returns the optional numbers of mesh entities of a given dimension.
3171 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3172 * \return const DataArrayInt * - the array of the entity numbers.
3173 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3175 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3177 if(meshDimRelToMaxExt==1)
3179 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3180 return l1->getNumberField();
3183 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3185 if(meshDimRelToMaxExt==1)
3186 return _name_coords;
3187 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3188 return l1->getNameField();
3192 * 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).
3194 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3195 * \param [in] gt - The input geometric type for which the part definition is requested.
3196 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3198 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3200 if(meshDimRelToMaxExt==1)
3201 return _part_coords;
3202 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3203 return l1->getPartDef(gt);
3206 int MEDFileUMesh::getNumberOfNodes() const
3208 const DataArrayDouble *coo(_coords);
3210 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3211 return coo->getNumberOfTuples();
3214 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3216 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3217 return l1->getNumberOfCells();
3220 bool MEDFileUMesh::hasImplicitPart() const
3225 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3227 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3230 void MEDFileUMesh::releaseImplicitPartIfAny() const
3234 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3236 std::size_t sz(st.getNumberOfItems());
3237 for(std::size_t i=0;i<sz;i++)
3239 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3240 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3241 if(st[i].getPflName().empty())
3242 m->computeNodeIdsAlg(nodesFetched);
3245 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3246 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3247 m2->computeNodeIdsAlg(nodesFetched);
3252 MEDFileMesh *MEDFileUMesh::cartesianize() const
3254 if(getAxisType()==AX_CART)
3257 return const_cast<MEDFileUMesh *>(this);
3261 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3262 const DataArrayDouble *coords(_coords);
3264 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3265 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3266 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3267 if((const MEDFileUMeshSplitL1 *)(*it))
3268 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3269 ret->_coords=coordsCart;
3270 ret->setAxisType(AX_CART);
3276 * Returns the optional numbers of mesh entities of a given dimension transformed using
3277 * DataArrayInt::invertArrayN2O2O2N().
3278 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3279 * \return const DataArrayInt * - the array of the entity numbers transformed using
3280 * DataArrayInt::invertArrayN2O2O2N().
3281 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3283 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3285 if(meshDimRelToMaxExt==1)
3287 if(!((const DataArrayInt *)_num_coords))
3288 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3289 return _rev_num_coords;
3291 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3292 return l1->getRevNumberField();
3296 * Returns a pointer to the node coordinates array of \a this mesh \b without
3297 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3299 DataArrayDouble *MEDFileUMesh::getCoords() const
3302 MCAuto<DataArrayDouble> tmp(_coords);
3303 if((DataArrayDouble *)tmp)
3311 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3312 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3314 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3315 * \param [in] grp - the name of the group whose mesh entities are included in the
3317 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3318 * according to the optional numbers of entities, if available.
3319 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3320 * delete this mesh using decrRef() as it is no more needed.
3321 * \throw If the name of a nonexistent group is specified.
3322 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3324 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3327 synchronizeTinyInfoOnLeaves();
3328 std::vector<std::string> tmp(1);
3330 return getGroups(meshDimRelToMaxExt,tmp,renum);
3334 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3335 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3337 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3338 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3340 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3341 * according to the optional numbers of entities, if available.
3342 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3343 * delete this mesh using decrRef() as it is no more needed.
3344 * \throw If a name of a nonexistent group is present in \a grps.
3345 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3347 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3350 synchronizeTinyInfoOnLeaves();
3351 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3352 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3353 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3354 zeRet->setName(grps[0]);
3355 return zeRet.retn();
3359 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3360 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3362 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3363 * \param [in] fam - the name of the family whose mesh entities are included in the
3365 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3366 * according to the optional numbers of entities, if available.
3367 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3368 * delete this mesh using decrRef() as it is no more needed.
3369 * \throw If a name of a nonexistent family is present in \a grps.
3370 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3372 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3375 synchronizeTinyInfoOnLeaves();
3376 std::vector<std::string> tmp(1);
3378 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3382 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3383 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3385 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3386 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3388 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3389 * according to the optional numbers of entities, if available.
3390 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3391 * delete this mesh using decrRef() as it is no more needed.
3392 * \throw If a name of a nonexistent family is present in \a fams.
3393 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3395 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3398 synchronizeTinyInfoOnLeaves();
3399 if(meshDimRelToMaxExt==1)
3401 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3402 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3403 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3407 std::vector<int> famIds=getFamiliesIds(fams);
3408 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3409 MCAuto<MEDCouplingUMesh> zeRet;
3411 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3413 zeRet=l1->getFamilyPart(0,0,renum);
3414 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3415 zeRet->setName(fams[0]);
3416 return zeRet.retn();
3420 * Returns ids of mesh entities contained in given families of a given dimension.
3421 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3423 * \param [in] fams - the names of the families of interest.
3424 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3425 * returned instead of ids.
3426 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3427 * numbers, if available and required, of mesh entities of the families. The caller
3428 * is to delete this array using decrRef() as it is no more needed.
3429 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3431 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3433 std::vector<int> famIds=getFamiliesIds(fams);
3434 if(meshDimRelToMaxExt==1)
3436 if((const DataArrayInt *)_fam_coords)
3438 MCAuto<DataArrayInt> da;
3440 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3442 da=_fam_coords->findIdsEqualList(0,0);
3444 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3449 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3451 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3453 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3455 return l1->getFamilyPartArr(0,0,renum);
3459 * Returns a MEDCouplingUMesh of a given relative dimension.
3460 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3461 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3462 * To build a valid MEDCouplingUMesh from the returned one in this case,
3463 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3464 * \param [in] meshDimRelToMax - the relative dimension of interest.
3465 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3466 * optional numbers of mesh entities.
3467 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3468 * delete using decrRef() as it is no more needed.
3469 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3471 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3474 synchronizeTinyInfoOnLeaves();
3475 if(meshDimRelToMaxExt==1)
3479 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3480 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3481 umesh->setCoords(cc);
3482 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3483 umesh->setName(getName());
3487 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3488 return l1->getWholeMesh(renum);
3491 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3493 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3494 return l1->getDistributionOfTypes();
3498 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3499 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3500 * optional numbers of mesh entities.
3501 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3502 * delete using decrRef() as it is no more needed.
3503 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3505 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3507 return getMeshAtLevel(0,renum);
3511 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3512 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3513 * optional numbers of mesh entities.
3514 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3515 * delete using decrRef() as it is no more needed.
3516 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3518 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3520 return getMeshAtLevel(-1,renum);
3524 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3525 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3526 * optional numbers of mesh entities.
3527 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3528 * delete using decrRef() as it is no more needed.
3529 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3531 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3533 return getMeshAtLevel(-2,renum);
3537 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3538 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3539 * optional numbers of mesh entities.
3540 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3541 * delete using decrRef() as it is no more needed.
3542 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3544 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3546 return getMeshAtLevel(-3,renum);
3550 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3551 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3552 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3553 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3555 void MEDFileUMesh::forceComputationOfParts() const
3557 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3559 const MEDFileUMeshSplitL1 *elt(*it);
3561 elt->forceComputationOfParts();
3566 * This method returns a vector of mesh parts containing each exactly one geometric type.
3567 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3568 * This method is only for memory aware users.
3569 * The returned pointers are **NOT** new object pointer. No need to mange them.
3571 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3574 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3575 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3579 * This method returns the part of \a this having the geometric type \a gt.
3580 * If such part is not existing an exception will be thrown.
3581 * The returned pointer is **NOT** new object pointer. No need to mange it.
3583 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3586 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3587 int lev=(int)cm.getDimension()-getMeshDimension();
3588 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3589 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3593 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3594 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3596 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3598 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3599 return sp->getGeoTypes();
3602 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3604 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3605 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3606 return sp->getNumberOfCellsWithType(ct);
3610 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3611 * \param [in] gt - the geometric type for which the family field is asked.
3612 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3613 * delete using decrRef() as it is no more needed.
3614 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3616 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3618 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3619 int lev=(int)cm.getDimension()-getMeshDimension();
3620 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3621 return sp->extractFamilyFieldOnGeoType(gt);
3625 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3626 * \param [in] gt - the geometric type for which the number field is asked.
3627 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3628 * delete using decrRef() as it is no more needed.
3629 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3631 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3633 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3634 int lev=(int)cm.getDimension()-getMeshDimension();
3635 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3636 return sp->extractNumberFieldOnGeoType(gt);
3640 * This method returns for specified geometric type \a gt the relative level to \a this.
3641 * If the relative level is empty an exception will be thrown.
3643 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3645 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3646 int ret((int)cm.getDimension()-getMeshDimension());
3647 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3651 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3653 if(meshDimRelToMaxExt==1)
3654 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3655 if(meshDimRelToMaxExt>1)
3656 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3657 int tracucedRk=-meshDimRelToMaxExt;
3658 if(tracucedRk>=(int)_ms.size())
3659 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3660 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3661 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3662 return _ms[tracucedRk];
3665 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3667 if(meshDimRelToMaxExt==1)
3668 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3669 if(meshDimRelToMaxExt>1)
3670 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3671 int tracucedRk=-meshDimRelToMaxExt;
3672 if(tracucedRk>=(int)_ms.size())
3673 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3674 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3675 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3676 return _ms[tracucedRk];
3679 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3681 if(-meshDimRelToMax>=(int)_ms.size())
3682 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3684 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3686 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3688 int ref=(*it)->getMeshDimension();
3689 if(ref+i!=meshDim-meshDimRelToMax)
3690 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3696 * Sets the node coordinates array of \a this mesh.
3697 * \param [in] coords - the new node coordinates array.
3698 * \throw If \a coords == \c NULL.
3700 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3703 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3704 if(coords==(DataArrayDouble *)_coords)
3706 coords->checkAllocated();
3707 int nbOfTuples=coords->getNumberOfTuples();
3710 _fam_coords=DataArrayInt::New();
3711 _fam_coords->alloc(nbOfTuples,1);
3712 _fam_coords->fillWithZero();
3713 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3714 if((MEDFileUMeshSplitL1 *)(*it))
3715 (*it)->setCoords(coords);
3719 * Removes all groups of a given dimension in \a this mesh.
3720 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3721 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3723 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3725 if(meshDimRelToMaxExt==1)
3727 if((DataArrayInt *)_fam_coords)
3728 _fam_coords->fillWithZero();
3731 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3732 l1->eraseFamilyField();
3737 * Removes all families with ids not present in the family fields of \a this mesh.
3739 void MEDFileUMesh::optimizeFamilies()
3741 std::vector<int> levs=getNonEmptyLevelsExt();
3742 std::set<int> allFamsIds;
3743 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3745 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3746 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3748 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3751 std::set<std::string> famNamesToKill;
3752 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3754 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3755 famNamesToKill.insert((*it).first);
3757 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3758 _families.erase(*it);
3759 std::vector<std::string> grpNamesToKill;
3760 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3762 std::vector<std::string> tmp;
3763 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3765 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3766 tmp.push_back(*it2);
3771 tmp.push_back((*it).first);
3773 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3778 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3779 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3780 * The boundary is built according to the following method:
3781 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3782 * coordinates array is extended).
3783 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3784 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3785 * might not be duplicated at all.
3786 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3787 * other side of the group is no more a neighbor)
3788 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3789 * bordering the newly created boundary use the newly computed nodes.
3790 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3791 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3793 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3794 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3796 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3797 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3798 * \sa clearNodeAndCellNumbers()
3800 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3801 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3803 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3804 typedef MCAuto<DataArrayInt> DAInt;
3806 std::vector<int> levs=getNonEmptyLevels();
3807 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3808 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3809 MUMesh m0=getMeshAtLevel(0);
3810 MUMesh m1=getMeshAtLevel(-1);
3811 int nbNodes=m0->getNumberOfNodes();
3812 MUMesh m11=getGroup(-1,grpNameM1);
3813 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3814 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3815 DAInt nodeIdsToDuplicate(tmp00);
3816 DAInt cellsToModifyConn0(tmp11);
3817 DAInt cellsToModifyConn1(tmp22);
3818 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3819 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3820 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3821 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3822 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3823 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3824 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3825 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3826 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3827 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3828 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3829 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3830 DAInt grpIds=getGroupArr(-1,grpNameM1);
3831 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3832 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3833 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3834 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3835 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3836 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3837 m0->setCoords(tmp0->getCoords());
3838 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3839 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3840 m1->setCoords(m0->getCoords());
3841 _coords=m0->getCoords(); _coords->incrRef();
3842 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3843 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3844 DataArrayInt * duplCells;
3845 m1->areCellsIncludedIn(m11, 0, duplCells);
3846 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3847 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3848 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3849 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3850 DAInt szOfCellGrpOfSameType(tmp00);
3851 DAInt idInMsOfCellGrpOfSameType(tmp11);
3853 newm1->setName(getName());
3854 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3856 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3857 DAInt newFam=DataArrayInt::New();
3858 newFam->alloc(newm1->getNumberOfCells(),1);
3859 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3860 // Positive ID for family of nodes, negative for all the rest.
3862 if (m1->getMeshDimension() == 0)
3863 idd=getMaxFamilyId()+1;
3865 idd=getMinFamilyId()-1;
3866 int globStart=0,start=0,end,globEnd;
3867 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3868 for(int i=0;i<nbOfChunks;i++)
3870 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3871 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3873 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3874 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3875 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3880 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3884 newm1->setCoords(getCoords());
3885 setMeshAtLevel(-1,newm1);
3886 setFamilyFieldArr(-1,newFam);
3887 std::string grpName2(grpNameM1); grpName2+="_dup";
3888 addFamily(grpName2,idd);
3889 addFamilyOnGrp(grpName2,grpName2);
3894 int newNbOfNodes=getCoords()->getNumberOfTuples();
3895 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3896 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3897 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3902 _rev_num_coords = 0;
3903 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
3904 it != _ms.end(); it++)
3907 (*it)->_rev_num = 0;
3909 nodesDuplicated=nodeIdsToDuplicate.retn();
3910 cellsModified=cellsToModifyConn0.retn();
3911 cellsNotModified=cellsToModifyConn1.retn();
3914 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
3915 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
3918 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3919 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3920 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3922 * \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.
3923 * 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.
3925 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3927 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3928 std::vector<int> levs=getNonEmptyLevels();
3930 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3931 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3934 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3936 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3937 std::vector<int> code1=m->getDistributionOfTypes();
3938 end=PutInThirdComponentOfCodeOffset(code1,start);
3939 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3940 bool hasChanged=m->unPolyze();
3941 DataArrayInt *fake=0;
3942 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3943 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3945 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3948 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3949 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3951 MCAuto<DataArrayInt> famField2,numField2;
3952 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3953 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3954 setMeshAtLevel(*it,m);
3955 std::vector<int> code2=m->getDistributionOfTypes();
3956 end=PutInThirdComponentOfCodeOffset(code2,start);
3957 newCode.insert(newCode.end(),code2.begin(),code2.end());
3959 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
3963 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3964 setFamilyFieldArr(*it,newFamField);
3968 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3969 setRenumFieldArr(*it,newNumField);
3974 newCode.insert(newCode.end(),code1.begin(),code1.end());
3980 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3981 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3982 o2nRenumCell=o2nRenumCellRet.retn();
3987 /*! \cond HIDDEN_ITEMS */
3988 struct MEDLoaderAccVisit1
3990 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3991 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3992 int _new_nb_of_nodes;
3997 * 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.
3998 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3999 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4000 * -1 values in returned array means that the corresponding old node is no more used.
4002 * \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
4003 * is modified in \a this.
4004 * \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
4007 DataArrayInt *MEDFileUMesh::zipCoords()
4009 const DataArrayDouble *coo(getCoords());
4011 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4012 int nbOfNodes(coo->getNumberOfTuples());
4013 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4014 std::vector<int> neLevs(getNonEmptyLevels());
4015 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4017 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4018 if(zeLev->isMeshStoredSplitByType())
4020 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4021 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4023 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4027 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4028 mesh->computeNodeIdsAlg(nodeIdsInUse);
4031 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4032 if(nbrOfNodesInUse==nbOfNodes)
4033 return 0;//no need to update _part_coords
4034 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4035 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4036 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4037 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4038 MCAuto<DataArrayInt> newFamCoords;
4039 MCAuto<DataArrayAsciiChar> newNameCoords;
4040 if((const DataArrayInt *)_fam_coords)
4041 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4042 MCAuto<DataArrayInt> newNumCoords;
4043 if((const DataArrayInt *)_num_coords)
4044 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4045 if((const DataArrayAsciiChar *)_name_coords)
4046 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4047 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4048 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4050 if((MEDFileUMeshSplitL1*)*it)
4052 (*it)->renumberNodesInConn(ret->begin());
4053 (*it)->setCoords(_coords);
4056 // updates _part_coords
4057 const PartDefinition *pc(_part_coords);
4060 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4061 _part_coords=tmpPD->composeWith(pc);
4067 * This method performs an extrusion along a path defined by \a m1D.
4068 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4069 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4070 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4071 * This method scans all levels in \a this
4072 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4074 * \param [in] m1D - the mesh defining the extrusion path.
4075 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4076 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4078 * \sa MEDCouplingUMesh::buildExtrudedMesh
4080 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4083 if(getMeshDimension()!=2)
4084 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4085 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4086 m1D->checkConsistencyLight();
4087 if(m1D->getMeshDimension()!=1)
4088 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4089 int nbRep(m1D->getNumberOfCells());
4090 std::vector<int> levs(getNonEmptyLevels());
4091 std::vector<std::string> grps(getGroupsNames());
4092 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4093 DataArrayDouble *coords(0);
4094 std::size_t nbOfLevsOut(levs.size()+1);
4095 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4096 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4098 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4099 item=item->clone(false);
4100 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4101 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4102 tmp->changeSpaceDimension(3+(*lev),0.);
4103 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4104 zeList.push_back(elt);
4106 coords=elt->getCoords();
4109 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4110 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4112 (*it)->setName(getName());
4113 (*it)->setCoords(coords);
4115 for(std::size_t ii=0;ii!=zeList.size();ii++)
4118 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4121 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4122 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4123 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4124 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4125 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4126 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4127 std::vector<const MEDCouplingUMesh *> elts(3);
4128 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4129 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4130 elt->setName(getName());
4133 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4134 ret->setMeshAtLevel(lev,elt);
4136 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4137 endLev=endLev->clone(false); endLev->setCoords(coords);
4138 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4139 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4140 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4141 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4142 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4143 endLev->setName(getName());
4144 ret->setMeshAtLevel(levs.back()-1,endLev);
4146 for(std::size_t ii=0;ii!=zeList.size();ii++)
4149 std::vector< MCAuto<DataArrayInt> > outGrps;
4150 std::vector< const DataArrayInt * > outGrps2;
4153 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4155 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4156 if(!grpArr->empty())
4158 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4159 int offset0(zeList[ii]->getNumberOfCells());
4160 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4161 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4162 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4163 grpArr2->setName(oss.str());
4164 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4165 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4166 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4167 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4172 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4174 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4175 if(!grpArr->empty())
4177 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4178 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4179 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4180 for(int iii=0;iii<nbRep;iii++)
4182 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4183 grpArrs2[iii]=grpArrs[iii];
4185 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4186 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4187 std::ostringstream grpName; grpName << *grp << "_extruded";
4188 grpArrExt->setName(grpName.str());
4189 outGrps.push_back(grpArrExt);
4190 outGrps2.push_back(grpArrExt);
4193 ret->setGroupsAtLevel(lev,outGrps2);
4195 std::vector< MCAuto<DataArrayInt> > outGrps;
4196 std::vector< const DataArrayInt * > outGrps2;
4197 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4199 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4200 if(grpArr1->empty())
4202 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4203 std::ostringstream grpName; grpName << *grp << "_top";
4204 grpArr2->setName(grpName.str());
4205 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4206 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4207 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4209 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4214 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4215 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4216 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4218 * \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
4219 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4220 * \param [in] eps - detection threshold for coordinates.
4221 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4223 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4225 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4228 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4229 int initialNbNodes(getNumberOfNodes());
4230 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4231 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4233 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4235 DataArrayDouble *zeCoords(m0->getCoords());
4236 ret->setMeshAtLevel(0,m0);
4237 std::vector<int> levs(getNonEmptyLevels());
4238 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4241 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4242 ret->setFamilyFieldArr(0,famFieldCpy);
4244 famField=getFamilyFieldAtLevel(1);
4247 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4248 fam->fillWithZero();
4249 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4250 ret->setFamilyFieldArr(1,fam);
4252 ret->copyFamGrpMapsFrom(*this);
4253 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4254 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4258 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4259 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4260 if(m1->getMeshDimension()!=0)
4263 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4264 }//kill unused notUsed var
4265 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4267 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4268 MCAuto<DataArrayInt> bSafe(b);
4271 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4272 throw INTERP_KERNEL::Exception(oss.str().c_str());
4274 b->applyLin(1,initialNbNodes);
4275 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4276 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4277 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4278 m1->renumberNodesInConn(renum->begin());
4280 m1->setCoords(zeCoords);
4281 ret->setMeshAtLevel(*lev,m1);
4282 famField=getFamilyFieldAtLevel(*lev);
4285 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4286 ret->setFamilyFieldArr(*lev,famFieldCpy);
4293 * This method converts all quadratic cells in \a this into linear cells.
4294 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4295 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4297 * \param [in] eps - detection threshold for coordinates.
4298 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4300 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4302 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4305 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4306 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4307 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4308 m0->convertQuadraticCellsToLinear();
4310 DataArrayDouble *zeCoords(m0->getCoords());
4311 ret->setMeshAtLevel(0,m0);
4312 std::vector<int> levs(getNonEmptyLevels());
4313 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4316 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4317 ret->setFamilyFieldArr(0,famFieldCpy);
4319 famField=getFamilyFieldAtLevel(1);
4322 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4323 ret->setFamilyFieldArr(1,fam);
4325 ret->copyFamGrpMapsFrom(*this);
4326 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4330 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4331 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4332 m1->convertQuadraticCellsToLinear();
4335 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4336 MCAuto<DataArrayInt> bSafe(b);
4339 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4340 throw INTERP_KERNEL::Exception(oss.str().c_str());
4342 m1->renumberNodesInConn(b->begin());
4343 m1->setCoords(zeCoords);
4344 ret->setMeshAtLevel(*lev,m1);
4345 famField=getFamilyFieldAtLevel(*lev);
4348 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4349 ret->setFamilyFieldArr(*lev,famFieldCpy);
4355 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4357 clearNonDiscrAttributes();
4358 forceComputationOfParts();
4359 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4360 std::vector<int> layer0;
4361 layer0.push_back(getAxisType());//0 i
4362 layer0.push_back(_order); //1 i
4363 layer0.push_back(_iteration);//2 i
4364 layer0.push_back(getSpaceDimension());//3 i
4365 tinyDouble.push_back(_time);//0 d
4366 tinyStr.push_back(_name);//0 s
4367 tinyStr.push_back(_desc_name);//1 s
4368 for(int i=0;i<getSpaceDimension();i++)
4369 tinyStr.push_back(_coords->getInfoOnComponent(i));
4370 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4371 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4373 tinyStr.push_back((*it).first);
4374 layer0.push_back((*it).second);
4376 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4377 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4379 layer0.push_back((int)(*it0).second.size());
4380 tinyStr.push_back((*it0).first);
4381 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4382 tinyStr.push_back(*it1);
4384 // sizeof(layer0)==4+aa+1+bb layer#0
4385 bigArrayD=_coords;// 0 bd
4386 bigArraysI.push_back(_fam_coords);// 0 bi
4387 bigArraysI.push_back(_num_coords);// 1 bi
4388 const PartDefinition *pd(_part_coords);
4390 layer0.push_back(-1);
4393 std::vector<int> tmp0;
4394 pd->serialize(tmp0,bigArraysI);
4395 tinyInt.push_back(tmp0.size());
4396 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4399 std::vector<int> layer1;
4400 std::vector<int> levs(getNonEmptyLevels());
4401 layer1.push_back((int)levs.size());// 0 i <- key
4402 layer1.insert(layer1.end(),levs.begin(),levs.end());
4403 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4405 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4406 lev->serialize(layer1,bigArraysI);
4408 // put layers all together.
4409 tinyInt.push_back(layer0.size());
4410 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4411 tinyInt.push_back(layer1.size());
4412 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4415 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4416 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4418 int sz0(tinyInt[0]);
4419 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4420 int sz1(tinyInt[sz0+1]);
4421 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4423 std::reverse(layer0.begin(),layer0.end());
4424 std::reverse(layer1.begin(),layer1.end());
4425 std::reverse(tinyDouble.begin(),tinyDouble.end());
4426 std::reverse(tinyStr.begin(),tinyStr.end());
4427 std::reverse(bigArraysI.begin(),bigArraysI.end());
4429 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4430 _order=layer0.back(); layer0.pop_back();
4431 _iteration=layer0.back(); layer0.pop_back();
4432 int spaceDim(layer0.back()); layer0.pop_back();
4433 _time=tinyDouble.back(); tinyDouble.pop_back();
4434 _name=tinyStr.back(); tinyStr.pop_back();
4435 _desc_name=tinyStr.back(); tinyStr.pop_back();
4436 _coords=bigArrayD; _coords->rearrange(spaceDim);
4437 for(int i=0;i<spaceDim;i++)
4439 _coords->setInfoOnComponent(i,tinyStr.back());
4442 int nbOfFams(layer0.back()); layer0.pop_back();
4444 for(int i=0;i<nbOfFams;i++)
4446 _families[tinyStr.back()]=layer0.back();
4447 tinyStr.pop_back(); layer0.pop_back();
4449 int nbGroups(layer0.back()); layer0.pop_back();
4451 for(int i=0;i<nbGroups;i++)
4453 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4454 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4455 std::vector<std::string> fams(nbOfFamsOnGrp);
4456 for(int j=0;j<nbOfFamsOnGrp;j++)
4458 fams[j]=tinyStr.back(); tinyStr.pop_back();
4460 _groups[grpName]=fams;
4462 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4463 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4465 int isPd(layer0.back()); layer0.pop_back();
4468 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4469 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4470 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4473 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4475 int nbLevs(layer1.back()); layer1.pop_back();
4476 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4478 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4479 _ms.resize(maxLev+1);
4480 for(int i=0;i<nbLevs;i++)
4484 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4489 * Adds a group of nodes to \a this mesh.
4490 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4491 * The ids should be sorted and different each other (MED file norm).
4493 * \warning this method can alter default "FAMILLE_ZERO" family.
4494 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4496 * \throw If the node coordinates array is not set.
4497 * \throw If \a ids == \c NULL.
4498 * \throw If \a ids->getName() == "".
4499 * \throw If \a ids does not respect the MED file norm.
4500 * \throw If a group with name \a ids->getName() already exists.
4502 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4504 const DataArrayDouble *coords(_coords);
4506 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4507 int nbOfNodes(coords->getNumberOfTuples());
4508 if(!((DataArrayInt *)_fam_coords))
4509 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4511 addGroupUnderground(true,ids,_fam_coords);
4515 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4517 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4518 * The ids should be sorted and different each other (MED file norm).
4520 * \warning this method can alter default "FAMILLE_ZERO" family.
4521 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4523 * \throw If the node coordinates array is not set.
4524 * \throw If \a ids == \c NULL.
4525 * \throw If \a ids->getName() == "".
4526 * \throw If \a ids does not respect the MED file norm.
4527 * \throw If a group with name \a ids->getName() already exists.
4529 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4531 std::vector<int> levs(getNonEmptyLevelsExt());
4532 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4534 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4535 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4537 if(meshDimRelToMaxExt==1)
4538 { addNodeGroup(ids); return ; }
4539 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4540 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4541 addGroupUnderground(false,ids,fam);
4545 * Changes a name of a family specified by its id.
4546 * \param [in] id - the id of the family of interest.
4547 * \param [in] newFamName - the new family name.
4548 * \throw If no family with the given \a id exists.
4550 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4552 std::string oldName=getFamilyNameGivenId(id);
4553 _families.erase(oldName);
4554 _families[newFamName]=id;
4558 * Removes a mesh of a given dimension.
4559 * \param [in] meshDimRelToMax - the relative dimension of interest.
4560 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4562 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4564 std::vector<int> levSet=getNonEmptyLevels();
4565 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4566 if(it==levSet.end())
4567 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4568 int pos=(-meshDimRelToMax);
4573 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4574 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4575 * \param [in] m - the new mesh to set.
4576 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4578 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4579 * another node coordinates array.
4580 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4581 * to the existing meshes of other levels of \a this mesh.
4583 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4585 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4586 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4590 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4591 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4592 * \param [in] m - the new mesh to set.
4593 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4594 * writing \a this mesh in a MED file.
4595 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4597 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4598 * another node coordinates array.
4599 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4600 * to the existing meshes of other levels of \a this mesh.
4602 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4604 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4605 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4608 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4610 dealWithTinyInfo(m);
4611 std::vector<int> levSet=getNonEmptyLevels();
4612 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4614 if((DataArrayDouble *)_coords==0)
4616 DataArrayDouble *c=m->getCoords();
4621 if(m->getCoords()!=_coords)
4622 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4623 int sz=(-meshDimRelToMax)+1;
4624 if(sz>=(int)_ms.size())
4626 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4630 return _ms[-meshDimRelToMax];
4634 * This method allows to set at once the content of different levels in \a this.
4635 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4637 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4638 * \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.
4639 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4641 * \throw If \a there is a null pointer in \a ms.
4642 * \sa MEDFileUMesh::setMeshAtLevel
4644 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4648 const MEDCouplingUMesh *mRef=ms[0];
4650 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4651 std::string name(mRef->getName());
4652 const DataArrayDouble *coo(mRef->getCoords());
4655 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4657 const MEDCouplingUMesh *cur(*it);
4659 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4660 if(coo!=cur->getCoords())
4661 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4662 int mdim=cur->getMeshDimension();
4663 zeDim=std::max(zeDim,mdim);
4664 if(s.find(mdim)!=s.end())
4665 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4667 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4669 int mdim=(*it)->getMeshDimension();
4670 setName((*it)->getName());
4671 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4677 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4678 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4679 * The given meshes must share the same node coordinates array.
4680 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4681 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4682 * create in \a this mesh.
4683 * \throw If \a ms is empty.
4684 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4685 * to the existing meshes of other levels of \a this mesh.
4686 * \throw If the meshes in \a ms do not share the same node coordinates array.
4687 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4688 * of the given meshes.
4689 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
4690 * \throw If names of some meshes in \a ms are equal.
4691 * \throw If \a ms includes a mesh with an empty name.
4693 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4696 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4697 int sz=(-meshDimRelToMax)+1;
4698 if(sz>=(int)_ms.size())
4700 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4701 DataArrayDouble *coo=checkMultiMesh(ms);
4702 if((DataArrayDouble *)_coords==0)
4708 if((DataArrayDouble *)_coords!=coo)
4709 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4710 std::vector<DataArrayInt *> corr;
4711 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4712 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
4713 setMeshAtLevel(meshDimRelToMax,m,renum);
4714 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4715 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4719 * Creates groups at a given level in \a this mesh from a sequence of
4720 * meshes each representing a group.
4721 * The given meshes must share the same node coordinates array.
4722 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4723 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4724 * create in \a this mesh.
4725 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4727 * \throw If \a ms is empty.
4728 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4729 * to the existing meshes of other levels of \a this mesh.
4730 * \throw If the meshes in \a ms do not share the same node coordinates array.
4731 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4732 * of the given meshes.
4733 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
4734 * \throw If names of some meshes in \a ms are equal.
4735 * \throw If \a ms includes a mesh with an empty name.
4737 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4740 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4741 int sz=(-meshDimRelToMax)+1;
4742 if(sz>=(int)_ms.size())
4744 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4745 DataArrayDouble *coo=checkMultiMesh(ms);
4746 if((DataArrayDouble *)_coords==0)
4752 if((DataArrayDouble *)_coords!=coo)
4753 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4754 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4755 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
4757 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4759 DataArrayInt *arr=0;
4760 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4764 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4765 throw INTERP_KERNEL::Exception(oss.str().c_str());
4768 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4769 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4772 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4774 const DataArrayDouble *ret=ms[0]->getCoords();
4775 int mdim=ms[0]->getMeshDimension();
4776 for(unsigned int i=1;i<ms.size();i++)
4778 ms[i]->checkConsistencyLight();
4779 if(ms[i]->getCoords()!=ret)
4780 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4781 if(ms[i]->getMeshDimension()!=mdim)
4782 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4784 return const_cast<DataArrayDouble *>(ret);
4788 * Sets the family field of a given relative dimension.
4789 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4790 * the family field is set.
4791 * \param [in] famArr - the array of the family field.
4792 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4793 * \throw If \a famArr has an invalid size.
4795 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4797 if(meshDimRelToMaxExt==1)
4804 DataArrayDouble *coo(_coords);
4806 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4807 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4812 if(meshDimRelToMaxExt>1)
4813 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4814 int traducedRk=-meshDimRelToMaxExt;
4815 if(traducedRk>=(int)_ms.size())
4816 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4817 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4818 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4819 return _ms[traducedRk]->setFamilyArr(famArr);
4823 * Sets the optional numbers of mesh entities of a given dimension.
4824 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4825 * \param [in] renumArr - the array of the numbers.
4826 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4827 * \throw If \a renumArr has an invalid size.
4829 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4831 if(meshDimRelToMaxExt==1)
4839 DataArrayDouble *coo(_coords);
4841 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4842 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4843 renumArr->incrRef();
4844 _num_coords=renumArr;
4848 if(meshDimRelToMaxExt>1)
4849 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4850 int traducedRk=-meshDimRelToMaxExt;
4851 if(traducedRk>=(int)_ms.size())
4852 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4853 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4854 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4855 return _ms[traducedRk]->setRenumArr(renumArr);
4859 * Sets the optional names of mesh entities of a given dimension.
4860 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4861 * \param [in] nameArr - the array of the names.
4862 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4863 * \throw If \a nameArr has an invalid size.
4865 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4867 if(meshDimRelToMaxExt==1)
4874 DataArrayDouble *coo(_coords);
4876 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4877 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4879 _name_coords=nameArr;
4882 if(meshDimRelToMaxExt>1)
4883 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4884 int traducedRk=-meshDimRelToMaxExt;
4885 if(traducedRk>=(int)_ms.size())
4886 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4887 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4888 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4889 return _ms[traducedRk]->setNameArr(nameArr);
4892 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4894 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4895 if((const MEDFileUMeshSplitL1 *)(*it))
4896 (*it)->synchronizeTinyInfo(*this);
4900 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4902 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4904 DataArrayInt *arr=_fam_coords;
4906 arr->changeValue(oldId,newId);
4907 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4909 MEDFileUMeshSplitL1 *sp=(*it);
4912 sp->changeFamilyIdArr(oldId,newId);
4917 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4919 std::list< MCAuto<DataArrayInt> > ret;
4920 const DataArrayInt *da(_fam_coords);
4922 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4923 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4925 const MEDFileUMeshSplitL1 *elt(*it);
4928 da=elt->getFamilyField();
4930 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4936 void MEDFileUMesh::computeRevNum() const
4938 if((const DataArrayInt *)_num_coords)
4941 int maxValue=_num_coords->getMaxValue(pos);
4942 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4946 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4948 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4951 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4953 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4954 ret.push_back((const DataArrayInt *)_fam_nodes);
4955 ret.push_back((const DataArrayInt *)_num_nodes);
4956 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4957 ret.push_back((const DataArrayInt *)_fam_cells);
4958 ret.push_back((const DataArrayInt *)_num_cells);
4959 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4960 ret.push_back((const DataArrayInt *)_fam_faces);
4961 ret.push_back((const DataArrayInt *)_num_faces);
4962 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4963 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4964 ret.push_back((const DataArrayInt *)_rev_num_cells);
4965 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4969 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4971 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4972 if((const DataArrayInt *)_fam_nodes)
4974 int val=_fam_nodes->getMaxValue(tmp);
4975 ret=std::max(ret,std::abs(val));
4977 if((const DataArrayInt *)_fam_cells)
4979 int val=_fam_cells->getMaxValue(tmp);
4980 ret=std::max(ret,std::abs(val));
4982 if((const DataArrayInt *)_fam_faces)
4984 int val=_fam_faces->getMaxValue(tmp);
4985 ret=std::max(ret,std::abs(val));
4990 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4992 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4993 if((const DataArrayInt *)_fam_nodes)
4995 int val=_fam_nodes->getMaxValue(tmp);
4996 ret=std::max(ret,val);
4998 if((const DataArrayInt *)_fam_cells)
5000 int val=_fam_cells->getMaxValue(tmp);
5001 ret=std::max(ret,val);
5003 if((const DataArrayInt *)_fam_faces)
5005 int val=_fam_faces->getMaxValue(tmp);
5006 ret=std::max(ret,val);
5011 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5013 int ret=std::numeric_limits<int>::max(),tmp=-1;
5014 if((const DataArrayInt *)_fam_nodes)
5016 int val=_fam_nodes->getMinValue(tmp);
5017 ret=std::min(ret,val);
5019 if((const DataArrayInt *)_fam_cells)
5021 int val=_fam_cells->getMinValue(tmp);
5022 ret=std::min(ret,val);
5024 if((const DataArrayInt *)_fam_faces)
5026 int val=_fam_faces->getMinValue(tmp);
5027 ret=std::min(ret,val);
5032 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5034 if(!MEDFileMesh::isEqual(other,eps,what))
5036 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5039 what="Mesh types differ ! This is structured and other is NOT !";
5042 const DataArrayInt *famc1=_fam_nodes;
5043 const DataArrayInt *famc2=otherC->_fam_nodes;
5044 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5046 what="Mismatch of families arr on nodes ! One is defined and not other !";
5051 bool ret=famc1->isEqual(*famc2);
5054 what="Families arr on nodes differ !";
5059 famc2=otherC->_fam_cells;
5060 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5062 what="Mismatch of families arr on cells ! One is defined and not other !";
5067 bool ret=famc1->isEqual(*famc2);
5070 what="Families arr on cells differ !";
5075 famc2=otherC->_fam_faces;
5076 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5078 what="Mismatch of families arr on faces ! One is defined and not other !";
5083 bool ret=famc1->isEqual(*famc2);
5086 what="Families arr on faces differ !";
5091 famc2=otherC->_num_nodes;
5092 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5094 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5099 bool ret=famc1->isEqual(*famc2);
5102 what="Numbering arr on nodes differ !";
5107 famc2=otherC->_num_cells;
5108 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5110 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5115 bool ret=famc1->isEqual(*famc2);
5118 what="Numbering arr on cells differ !";
5123 famc2=otherC->_num_faces;
5124 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5126 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5131 bool ret=famc1->isEqual(*famc2);
5134 what="Numbering arr on faces differ !";
5138 const DataArrayAsciiChar *d1=_names_cells;
5139 const DataArrayAsciiChar *d2=otherC->_names_cells;
5140 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5142 what="Mismatch of naming arr on cells ! One is defined and not other !";
5147 bool ret=d1->isEqual(*d2);
5150 what="Naming arr on cells differ !";
5155 d2=otherC->_names_faces;
5156 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5158 what="Mismatch of naming arr on faces ! One is defined and not other !";
5163 bool ret=d1->isEqual(*d2);
5166 what="Naming arr on faces differ !";
5171 d2=otherC->_names_nodes;
5172 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5174 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5179 bool ret=d1->isEqual(*d2);
5182 what="Naming arr on nodes differ !";
5189 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5191 MEDFileMesh::clearNonDiscrAttributes();
5192 const DataArrayInt *tmp=_fam_nodes;
5194 (const_cast<DataArrayInt *>(tmp))->setName("");
5197 (const_cast<DataArrayInt *>(tmp))->setName("");
5200 (const_cast<DataArrayInt *>(tmp))->setName("");
5203 (const_cast<DataArrayInt *>(tmp))->setName("");
5206 (const_cast<DataArrayInt *>(tmp))->setName("");
5209 (const_cast<DataArrayInt *>(tmp))->setName("");
5213 * Returns ids of mesh entities contained in given families of a given dimension.
5214 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5216 * \param [in] fams - the names of the families of interest.
5217 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5218 * returned instead of ids.
5219 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5220 * numbers, if available and required, of mesh entities of the families. The caller
5221 * is to delete this array using decrRef() as it is no more needed.
5222 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5224 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5226 std::vector<int> famIds(getFamiliesIds(fams));
5227 switch(meshDimRelToMaxExt)
5231 if((const DataArrayInt *)_fam_nodes)
5233 MCAuto<DataArrayInt> da;
5235 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5237 da=_fam_nodes->findIdsEqualList(0,0);
5239 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5244 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5249 if((const DataArrayInt *)_fam_cells)
5251 MCAuto<DataArrayInt> da;
5253 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5255 da=_fam_cells->findIdsEqualList(0,0);
5257 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5262 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5267 if((const DataArrayInt *)_fam_faces)
5269 MCAuto<DataArrayInt> da;
5271 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5273 da=_fam_faces->findIdsEqualList(0,0);
5275 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5280 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5284 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5286 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5290 * Sets the family field of a given relative dimension.
5291 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5292 * the family field is set.
5293 * \param [in] famArr - the array of the family field.
5294 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5295 * \throw If \a famArr has an invalid size.
5296 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5298 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5300 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5302 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5303 switch(meshDimRelToMaxExt)
5307 int nbCells(mesh->getNumberOfCells());
5309 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5315 int nbNodes(mesh->getNumberOfNodes());
5317 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5323 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5325 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5330 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5337 * Sets the optional numbers of mesh entities of a given dimension.
5338 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5339 * \param [in] renumArr - the array of the numbers.
5340 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5341 * \throw If \a renumArr has an invalid size.
5342 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5344 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5346 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5348 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5349 switch(meshDimRelToMaxExt)
5353 int nbCells=mesh->getNumberOfCells();
5354 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5355 _num_cells=renumArr;
5360 int nbNodes=mesh->getNumberOfNodes();
5361 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5362 _num_nodes=renumArr;
5367 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5368 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5369 _num_faces=renumArr;
5373 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5376 renumArr->incrRef();
5380 * Sets the optional names of mesh entities of a given dimension.
5381 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5382 * \param [in] nameArr - the array of the names.
5383 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5384 * \throw If \a nameArr has an invalid size.
5386 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5388 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5390 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5391 switch(meshDimRelToMaxExt)
5395 int nbCells=mesh->getNumberOfCells();
5396 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5397 _names_cells=nameArr;
5402 int nbNodes=mesh->getNumberOfNodes();
5403 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5404 _names_nodes=nameArr;
5409 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5410 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5411 _names_cells=nameArr;
5414 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5421 * Adds a group of nodes to \a this mesh.
5422 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5423 * The ids should be sorted and different each other (MED file norm).
5425 * \warning this method can alter default "FAMILLE_ZERO" family.
5426 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5428 * \throw If the node coordinates array is not set.
5429 * \throw If \a ids == \c NULL.
5430 * \throw If \a ids->getName() == "".
5431 * \throw If \a ids does not respect the MED file norm.
5432 * \throw If a group with name \a ids->getName() already exists.
5434 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5440 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5442 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5443 * The ids should be sorted and different each other (MED file norm).
5445 * \warning this method can alter default "FAMILLE_ZERO" family.
5446 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5448 * \throw If the node coordinates array is not set.
5449 * \throw If \a ids == \c NULL.
5450 * \throw If \a ids->getName() == "".
5451 * \throw If \a ids does not respect the MED file norm.
5452 * \throw If a group with name \a ids->getName() already exists.
5454 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5456 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5457 addGroupUnderground(false,ids,fam);
5462 * Returns the family field for mesh entities of a given dimension.
5463 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5464 * \return const DataArrayInt * - the family field. It is an array of ids of families
5465 * each mesh entity belongs to. It can be \c NULL.
5466 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5468 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5470 switch(meshDimRelToMaxExt)
5479 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5484 * Returns the family field for mesh entities of a given dimension.
5485 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5486 * \return const DataArrayInt * - the family field. It is an array of ids of families
5487 * each mesh entity belongs to. It can be \c NULL.
5488 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5490 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5492 switch(meshDimRelToMaxExt)
5501 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5506 * Returns the optional numbers of mesh entities of a given dimension.
5507 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5508 * \return const DataArrayInt * - the array of the entity numbers.
5509 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5510 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5512 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5514 switch(meshDimRelToMaxExt)
5523 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5528 * Returns the optional numbers of mesh entities of a given dimension transformed using
5529 * DataArrayInt::invertArrayN2O2O2N().
5530 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5531 * \return const DataArrayInt * - the array of the entity numbers transformed using
5532 * DataArrayInt::invertArrayN2O2O2N().
5533 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5534 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5536 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5538 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5539 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5540 if(meshDimRelToMaxExt==0)
5542 if((const DataArrayInt *)_num_cells)
5545 int maxValue=_num_cells->getMaxValue(pos);
5546 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5547 return _rev_num_cells;
5550 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5554 if((const DataArrayInt *)_num_nodes)
5557 int maxValue=_num_nodes->getMaxValue(pos);
5558 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5559 return _rev_num_nodes;
5562 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5566 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5568 switch(meshDimRelToMaxExt)
5571 return _names_cells;
5573 return _names_nodes;
5575 return _names_faces;
5577 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5582 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5583 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5585 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5587 std::vector<int> ret(1);
5592 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5593 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5595 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5597 std::vector<int> ret(2);
5603 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5605 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5607 std::vector<int> ret;
5608 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5619 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5621 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5623 std::vector<int> ret;
5624 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5635 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5637 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5639 std::vector<int> ret;
5640 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5651 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5653 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5655 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5659 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5661 DataArrayInt *arr=_fam_nodes;
5663 arr->changeValue(oldId,newId);
5666 arr->changeValue(oldId,newId);
5669 arr->changeValue(oldId,newId);
5672 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5674 std::list< MCAuto<DataArrayInt> > ret;
5675 const DataArrayInt *da(_fam_nodes);
5677 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5680 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5683 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5687 void MEDFileStructuredMesh::deepCpyAttributes()
5689 if((const DataArrayInt*)_fam_nodes)
5690 _fam_nodes=_fam_nodes->deepCopy();
5691 if((const DataArrayInt*)_num_nodes)
5692 _num_nodes=_num_nodes->deepCopy();
5693 if((const DataArrayAsciiChar*)_names_nodes)
5694 _names_nodes=_names_nodes->deepCopy();
5695 if((const DataArrayInt*)_fam_cells)
5696 _fam_cells=_fam_cells->deepCopy();
5697 if((const DataArrayInt*)_num_cells)
5698 _num_cells=_num_cells->deepCopy();
5699 if((const DataArrayAsciiChar*)_names_cells)
5700 _names_cells=_names_cells->deepCopy();
5701 if((const DataArrayInt*)_fam_faces)
5702 _fam_faces=_fam_faces->deepCopy();
5703 if((const DataArrayInt*)_num_faces)
5704 _num_faces=_num_faces->deepCopy();
5705 if((const DataArrayAsciiChar*)_names_faces)
5706 _names_faces=_names_faces->deepCopy();
5707 if((const DataArrayInt*)_rev_num_nodes)
5708 _rev_num_nodes=_rev_num_nodes->deepCopy();
5709 if((const DataArrayInt*)_rev_num_cells)
5710 _rev_num_cells=_rev_num_cells->deepCopy();
5714 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5716 * \return a pointer to cartesian mesh that need to be managed by the caller.
5717 * \warning the returned pointer has to be managed by the caller.
5721 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5722 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5723 * \param [in] renum - it must be \c false.
5724 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5725 * delete using decrRef() as it is no more needed.
5727 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
5731 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5732 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5733 switch(meshDimRelToMax)
5739 return const_cast<MEDCouplingStructuredMesh *>(m);
5744 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5745 buildMinusOneImplicitPartIfNeeded();
5746 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
5752 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5756 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
5758 std::vector<int> ret;
5759 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
5760 if(famCells && famCells->presenceOfValue(ret))
5762 if(famFaces && famFaces->presenceOfValue(ret))
5767 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
5769 std::vector<int> ret(getFamsNonEmptyLevels(fams));
5770 const DataArrayInt *famNodes(_fam_nodes);
5771 if(famNodes && famNodes->presenceOfValue(ret))
5777 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5778 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5779 * \return int - the number of entities.
5780 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5782 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5784 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5786 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5787 switch(meshDimRelToMaxExt)
5790 return cmesh->getNumberOfCells();
5792 return cmesh->getNumberOfNodes();
5794 return cmesh->getNumberOfCellsOfSubLevelMesh();
5796 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5800 int MEDFileStructuredMesh::getNumberOfNodes() const
5802 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5804 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5805 return cmesh->getNumberOfNodes();
5808 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5810 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5812 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5813 switch(meshDimRelToMaxExt)
5816 return cmesh->getNumberOfCells();
5818 return cmesh->getNumberOfCellsOfSubLevelMesh();
5820 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5824 bool MEDFileStructuredMesh::hasImplicitPart() const
5830 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5832 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5834 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5835 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5838 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5839 if(cm.getReverseExtrudedType()!=gt)
5840 throw INTERP_KERNEL::Exception(MSG);
5841 buildImplicitPart();
5842 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5846 if(gt!=zeFaceMesh->getCellModelEnum())
5847 throw INTERP_KERNEL::Exception(MSG);
5848 return zeFaceMesh->getNumberOfCells();
5852 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5854 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5856 buildImplicitPart();
5859 void MEDFileStructuredMesh::buildImplicitPart() const
5861 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5863 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5864 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5867 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5869 _faces_if_necessary=0;
5873 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5874 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5876 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5878 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5881 return _faces_if_necessary;
5884 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5886 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5888 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5889 switch(meshDimRelToMax)
5893 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5898 int mdim(cmesh->getMeshDimension());
5900 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5901 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5905 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5909 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
5911 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5914 return getNumberOfCellsAtLevel(0);
5917 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5919 if(st.getNumberOfItems()!=1)
5920 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 !");
5921 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5922 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5923 if(getNumberOfNodes()!=(int)nodesFetched.size())
5924 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5925 if(st[0].getPflName().empty())
5927 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5930 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5931 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5932 int sz(nodesFetched.size());
5933 for(const int *work=arr->begin();work!=arr->end();work++)
5935 std::vector<int> conn;
5936 cmesh->getNodeIdsOfCell(*work,conn);
5937 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5938 if(*it>=0 && *it<sz)
5939 nodesFetched[*it]=true;
5941 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5945 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5947 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5951 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5952 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
5954 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5955 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5957 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5960 if(!mrs || mrs->isCellFamilyFieldReading())
5962 famCells=DataArrayInt::New();
5963 famCells->alloc(nbOfElt,1);
5964 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
5967 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5970 if(!mrs || mrs->isCellNumFieldReading())
5972 numCells=DataArrayInt::New();
5973 numCells->alloc(nbOfElt,1);
5974 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
5977 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5980 if(!mrs || mrs->isCellNameFieldReading())
5982 namesCells=DataArrayAsciiChar::New();
5983 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5984 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
5985 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5990 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5992 setName(strm->getName());
5993 setDescription(strm->getDescription());
5994 setUnivName(strm->getUnivName());
5995 setIteration(strm->getIteration());
5996 setOrder(strm->getOrder());
5997 setTimeValue(strm->getTime());
5998 setTimeUnit(strm->getTimeUnit());
5999 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6000 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6001 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6004 if(!mrs || mrs->isNodeFamilyFieldReading())
6006 int nbNodes(getNumberOfNodes());
6008 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6009 _fam_nodes=DataArrayInt::New();
6010 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6011 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...
6012 _fam_nodes->fillWithZero();
6013 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6016 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6019 if(!mrs || mrs->isNodeNumFieldReading())
6021 _num_nodes=DataArrayInt::New();
6022 _num_nodes->alloc(nbOfElt,1);
6023 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6026 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6029 if(!mrs || mrs->isNodeNameFieldReading())
6031 _names_nodes=DataArrayAsciiChar::New();
6032 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6033 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6034 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6037 int meshDim(getStructuredMesh()->getMeshDimension());
6038 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6040 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6043 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6045 int meshDim(getStructuredMesh()->getMeshDimension());
6046 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6048 if((const DataArrayInt *)_fam_cells)
6049 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6050 if((const DataArrayInt *)_fam_faces)
6051 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6052 if((const DataArrayInt *)_fam_nodes)
6053 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6054 if((const DataArrayInt *)_num_cells)
6055 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6056 if((const DataArrayInt *)_num_faces)
6057 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6058 if((const DataArrayInt *)_num_nodes)
6059 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6060 if((const DataArrayAsciiChar *)_names_cells)
6062 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6064 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6065 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6066 throw INTERP_KERNEL::Exception(oss.str().c_str());
6068 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6070 if((const DataArrayAsciiChar *)_names_faces)
6072 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6074 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6075 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6076 throw INTERP_KERNEL::Exception(oss.str().c_str());
6078 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6080 if((const DataArrayAsciiChar *)_names_nodes)
6082 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6084 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6085 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6086 throw INTERP_KERNEL::Exception(oss.str().c_str());
6088 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6091 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6095 * Returns an empty instance of MEDFileCMesh.
6096 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6097 * mesh using decrRef() as it is no more needed.
6099 MEDFileCMesh *MEDFileCMesh::New()
6101 return new MEDFileCMesh;
6105 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6106 * file. The first mesh in the file is loaded.
6107 * \param [in] fileName - the name of MED file to read.
6108 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6109 * mesh using decrRef() as it is no more needed.
6110 * \throw If the file is not readable.
6111 * \throw If there is no meshes in the file.
6112 * \throw If the mesh in the file is not a Cartesian one.
6114 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6116 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6119 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6120 throw INTERP_KERNEL::Exception(oss.str().c_str());
6122 MEDFileUtilities::CheckFileForRead(fileName);
6123 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6125 MEDCoupling::MEDCouplingMeshType meshType;
6127 MEDCoupling::MEDCouplingAxisType dummy3;
6128 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6129 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
6133 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6134 * file. The mesh to load is specified by its name and numbers of a time step and an
6136 * \param [in] fileName - the name of MED file to read.
6137 * \param [in] mName - the name of the mesh to read.
6138 * \param [in] dt - the number of a time step.
6139 * \param [in] it - the number of an iteration.
6140 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6141 * mesh using decrRef() as it is no more needed.
6142 * \throw If the file is not readable.
6143 * \throw If there is no mesh with given attributes in the file.
6144 * \throw If the mesh in the file is not a Cartesian one.
6146 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6148 MEDFileUtilities::CheckFileForRead(fileName);
6149 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6150 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6153 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6155 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6158 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6160 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6161 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6166 * Returns the dimension on cells in \a this mesh.
6167 * \return int - the mesh dimension.
6168 * \throw If there are no cells in this mesh.
6170 int MEDFileCMesh::getMeshDimension() const
6172 if(!((const MEDCouplingCMesh*)_cmesh))
6173 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6174 return _cmesh->getMeshDimension();
6178 * Returns the dimension on nodes in \a this mesh.
6179 * \return int - the space dimension.
6180 * \throw If there are no cells in this mesh.
6182 int MEDFileCMesh::getSpaceDimension() const
6184 if(!((const MEDCouplingCMesh*)_cmesh))
6185 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6186 return _cmesh->getSpaceDimension();
6190 * Returns a string describing \a this mesh.
6191 * \return std::string - the mesh information string.
6193 std::string MEDFileCMesh::simpleRepr() const
6195 return MEDFileStructuredMesh::simpleRepr();
6199 * Returns a full textual description of \a this mesh.
6200 * \return std::string - the string holding the mesh description.
6202 std::string MEDFileCMesh::advancedRepr() const
6204 return simpleRepr();
6207 MEDFileMesh *MEDFileCMesh::shallowCpy() const
6209 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6213 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6215 return new MEDFileCMesh;
6218 MEDFileMesh *MEDFileCMesh::deepCopy() const
6220 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6221 ret->deepCpyEquivalences(*this);
6222 if((const MEDCouplingCMesh*)_cmesh)
6223 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6224 ret->deepCpyAttributes();
6229 * Checks if \a this and another mesh are equal.
6230 * \param [in] other - the mesh to compare with.
6231 * \param [in] eps - a precision used to compare real values.
6232 * \param [in,out] what - the string returning description of unequal data.
6233 * \return bool - \c true if the meshes are equal, \c false, else.
6235 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6237 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6239 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6242 what="Mesh types differ ! This is cartesian and other is NOT !";
6245 clearNonDiscrAttributes();
6246 otherC->clearNonDiscrAttributes();
6247 const MEDCouplingCMesh *coo1=_cmesh;
6248 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6249 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6251 what="Mismatch of cartesian meshes ! One is defined and not other !";
6256 bool ret=coo1->isEqual(coo2,eps);
6259 what="cartesian meshes differ !";
6267 * Clears redundant attributes of incorporated data arrays.
6269 void MEDFileCMesh::clearNonDiscrAttributes() const
6271 MEDFileStructuredMesh::clearNonDiscrAttributes();
6272 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6275 MEDFileCMesh::MEDFileCMesh()
6279 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6282 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6284 catch(INTERP_KERNEL::Exception& e)
6289 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6291 MEDCoupling::MEDCouplingMeshType meshType;
6294 MEDCoupling::MEDCouplingAxisType axType;
6295 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6296 if(meshType!=CARTESIAN)
6298 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6299 throw INTERP_KERNEL::Exception(oss.str().c_str());
6301 MEDFileCMeshL2 loaderl2;
6302 loaderl2.loadAll(fid,mid,mName,dt,it);
6303 setAxisType(axType);
6304 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6307 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6311 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6312 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6314 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6316 synchronizeTinyInfoOnLeaves();
6320 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6322 synchronizeTinyInfoOnLeaves();
6327 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6328 * \param [in] m - the new MEDCouplingCMesh to refer to.
6329 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6332 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6334 dealWithTinyInfo(m);
6340 MEDFileMesh *MEDFileCMesh::cartesianize() const
6342 if(getAxisType()==AX_CART)
6345 return const_cast<MEDFileCMesh *>(this);
6349 const MEDCouplingCMesh *cmesh(getMesh());
6351 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6352 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6353 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6354 clmesh->setCoords(coords);
6355 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6356 ret->MEDFileStructuredMesh::operator=(*this);
6357 ret->setMesh(clmesh);
6358 ret->setAxisType(AX_CART);
6363 void MEDFileCMesh::writeLL(med_idt fid) const
6365 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6366 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6367 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6368 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6369 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6370 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6371 int spaceDim(_cmesh->getSpaceDimension());
6372 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6373 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6374 for(int i=0;i<spaceDim;i++)
6376 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6378 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6379 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
6380 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
6382 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6384 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6385 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6386 for(int i=0;i<spaceDim;i++)
6388 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6389 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6392 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6393 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6396 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6398 const MEDCouplingCMesh *cmesh=_cmesh;
6401 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6402 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6403 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6404 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6407 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6409 return new MEDFileCurveLinearMesh;
6412 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6414 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6417 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6418 throw INTERP_KERNEL::Exception(oss.str().c_str());
6420 MEDFileUtilities::CheckFileForRead(fileName);
6421 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6423 MEDCoupling::MEDCouplingMeshType meshType;
6424 MEDCoupling::MEDCouplingAxisType dummy3;
6426 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6427 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6430 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6432 MEDFileUtilities::CheckFileForRead(fileName);
6433 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6434 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6437 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6439 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6442 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6444 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6445 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6449 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6451 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6455 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6457 return new MEDFileCurveLinearMesh;
6460 MEDFileMesh *MEDFileCurveLinearMesh::deepCopy() const
6462 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6463 ret->deepCpyEquivalences(*this);
6464 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6465 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6466 ret->deepCpyAttributes();
6470 int MEDFileCurveLinearMesh::getMeshDimension() const
6472 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6473 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6474 return _clmesh->getMeshDimension();
6477 std::string MEDFileCurveLinearMesh::simpleRepr() const
6479 return MEDFileStructuredMesh::simpleRepr();
6482 std::string MEDFileCurveLinearMesh::advancedRepr() const
6484 return simpleRepr();
6487 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6489 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6491 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6494 what="Mesh types differ ! This is curve linear and other is NOT !";
6497 clearNonDiscrAttributes();
6498 otherC->clearNonDiscrAttributes();
6499 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6500 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6501 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6503 what="Mismatch of curve linear meshes ! One is defined and not other !";
6508 bool ret=coo1->isEqual(coo2,eps);
6511 what="curve linear meshes differ !";
6518 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6520 MEDFileStructuredMesh::clearNonDiscrAttributes();
6521 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6524 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6526 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6529 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6530 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6531 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6532 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6535 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6537 synchronizeTinyInfoOnLeaves();
6541 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6543 dealWithTinyInfo(m);
6549 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6551 if(getAxisType()==AX_CART)
6554 return const_cast<MEDFileCurveLinearMesh *>(this);
6558 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6560 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6561 const DataArrayDouble *coords(mesh->getCoords());
6563 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6564 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6565 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6566 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6567 mesh2->setCoords(coordsCart);
6568 ret->setMesh(mesh2);
6569 ret->setAxisType(AX_CART);
6574 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6576 synchronizeTinyInfoOnLeaves();
6580 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6584 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6587 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6589 catch(INTERP_KERNEL::Exception& e)
6594 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6596 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6597 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6598 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6599 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6600 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6601 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6602 int spaceDim=_clmesh->getSpaceDimension();
6603 int meshDim=_clmesh->getMeshDimension();
6604 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6605 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6606 const DataArrayDouble *coords=_clmesh->getCoords();
6608 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6609 for(int i=0;i<spaceDim;i++)
6611 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6613 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6614 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
6615 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
6617 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6619 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6620 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6621 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6622 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6624 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6626 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6627 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6630 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6632 MEDCoupling::MEDCouplingMeshType meshType;
6635 MEDCoupling::MEDCouplingAxisType axType;
6636 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6637 setAxisType(axType);
6638 if(meshType!=CURVE_LINEAR)
6640 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6641 throw INTERP_KERNEL::Exception(oss.str().c_str());
6643 MEDFileCLMeshL2 loaderl2;
6644 loaderl2.loadAll(fid,mid,mName,dt,it);
6645 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6648 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6651 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6653 return new MEDFileMeshMultiTS;
6656 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6658 return new MEDFileMeshMultiTS(fileName);
6661 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6663 return new MEDFileMeshMultiTS(fileName,mName);
6666 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
6668 MCAuto<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6669 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6671 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6672 if((const MEDFileMesh *)*it)
6673 meshOneTs[i]=(*it)->deepCopy();
6674 ret->_mesh_one_ts=meshOneTs;
6678 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6680 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
6683 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6685 std::vector<const BigMemoryObject *> ret;
6686 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6687 ret.push_back((const MEDFileMesh *)*it);
6691 std::string MEDFileMeshMultiTS::getName() const
6693 if(_mesh_one_ts.empty())
6694 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6695 return _mesh_one_ts[0]->getName();
6698 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6700 std::string oldName(getName());
6701 std::vector< std::pair<std::string,std::string> > v(1);
6702 v[0].first=oldName; v[0].second=newMeshName;
6706 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6709 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6711 MEDFileMesh *cur(*it);
6713 ret=cur->changeNames(modifTab) || ret;
6718 void MEDFileMeshMultiTS::cartesianizeMe()
6720 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6722 MEDFileMesh *cur(*it);
6725 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
6731 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6733 if(_mesh_one_ts.empty())
6734 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6735 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6738 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6741 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6742 _mesh_one_ts.resize(1);
6743 mesh1TimeStep->incrRef();
6744 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
6745 _mesh_one_ts[0]=mesh1TimeStep;
6748 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
6750 if ( MEDFileMesh* m = getOneTimeStep() )
6751 return m->getJoints();
6756 * \brief Set Joints that are common to all time-stamps
6758 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
6760 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6762 (*it)->setJoints( joints );
6766 void MEDFileMeshMultiTS::write(med_idt fid) const
6768 MEDFileJoints *joints(getJoints());
6769 bool jointsWritten(false);
6771 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6773 if ( jointsWritten )
6774 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
6776 jointsWritten = true;
6778 (*it)->copyOptionsFrom(*this);
6782 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
6785 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6787 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6788 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6789 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6790 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6794 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6796 MEDFileJoints* joints = 0;
6797 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
6799 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
6800 joints = getOneTimeStep()->getJoints();
6803 _mesh_one_ts.clear(); //for the moment to be improved
6804 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
6807 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6811 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6814 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6817 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6818 throw INTERP_KERNEL::Exception(oss.str().c_str());
6820 MEDFileUtilities::CheckFileForRead(fileName);
6821 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6823 MEDCoupling::MEDCouplingMeshType meshType;
6825 MEDCoupling::MEDCouplingAxisType dummy3;
6826 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6827 loadFromFile(fileName,ms.front());
6829 catch(INTERP_KERNEL::Exception& e)
6834 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6837 loadFromFile(fileName,mName);
6839 catch(INTERP_KERNEL::Exception& e)
6844 MEDFileMeshes *MEDFileMeshes::New()
6846 return new MEDFileMeshes;
6849 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6851 return new MEDFileMeshes(fileName);
6854 void MEDFileMeshes::write(med_idt fid) const
6856 checkConsistencyLight();
6857 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6859 (*it)->copyOptionsFrom(*this);
6864 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6866 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6867 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6868 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6869 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6870 checkConsistencyLight();
6874 int MEDFileMeshes::getNumberOfMeshes() const
6876 return _meshes.size();
6879 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6881 return new MEDFileMeshesIterator(this);
6884 /** Return a borrowed reference (caller is not responsible) */
6885 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6887 if(i<0 || i>=(int)_meshes.size())
6889 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6890 throw INTERP_KERNEL::Exception(oss.str().c_str());
6892 return _meshes[i]->getOneTimeStep();
6895 /** Return a borrowed reference (caller is not responsible) */
6896 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6898 std::vector<std::string> ms=getMeshesNames();
6899 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6902 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6903 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6904 throw INTERP_KERNEL::Exception(oss.str().c_str());
6906 return getMeshAtPos((int)std::distance(ms.begin(),it));
6909 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6911 std::vector<std::string> ret(_meshes.size());
6913 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6915 const MEDFileMeshMultiTS *f=(*it);
6918 ret[i]=f->getName();
6922 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6923 throw INTERP_KERNEL::Exception(oss.str().c_str());
6929 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6932 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6934 MEDFileMeshMultiTS *cur(*it);
6936 ret=cur->changeNames(modifTab) || ret;
6941 void MEDFileMeshes::cartesianizeMe()
6943 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6945 MEDFileMeshMultiTS *cur(*it);
6947 cur->cartesianizeMe();
6951 void MEDFileMeshes::resize(int newSize)
6953 _meshes.resize(newSize);
6956 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6959 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6960 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6961 elt->setOneTimeStep(mesh);
6962 _meshes.push_back(elt);
6965 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6968 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6969 if(i>=(int)_meshes.size())
6970 _meshes.resize(i+1);
6971 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6972 elt->setOneTimeStep(mesh);
6976 void MEDFileMeshes::destroyMeshAtPos(int i)
6978 if(i<0 || i>=(int)_meshes.size())
6980 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6981 throw INTERP_KERNEL::Exception(oss.str().c_str());
6983 _meshes.erase(_meshes.begin()+i);
6986 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6988 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6990 _meshes.resize(ms.size());
6991 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6992 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6995 MEDFileMeshes::MEDFileMeshes()
6999 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
7002 loadFromFile(fileName);
7004 catch(INTERP_KERNEL::Exception& /*e*/)
7008 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7010 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7012 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7013 if((const MEDFileMeshMultiTS *)*it)
7014 meshes[i]=(*it)->deepCopy();
7015 MCAuto<MEDFileMeshes> ret=MEDFileMeshes::New();
7016 ret->_meshes=meshes;
7020 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7022 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7025 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7027 std::vector<const BigMemoryObject *> ret;
7028 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7029 ret.push_back((const MEDFileMeshMultiTS *)*it);
7033 std::string MEDFileMeshes::simpleRepr() const
7035 std::ostringstream oss;
7036 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7037 simpleReprWithoutHeader(oss);
7041 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7043 int nbOfMeshes=getNumberOfMeshes();
7044 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7045 std::vector<std::string> mns=getMeshesNames();
7046 for(int i=0;i<nbOfMeshes;i++)
7047 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7050 void MEDFileMeshes::checkConsistencyLight() const
7052 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7054 std::set<std::string> s;
7055 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7057 const MEDFileMeshMultiTS *elt=(*it);
7060 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7061 throw INTERP_KERNEL::Exception(oss.str().c_str());
7063 std::size_t sz=s.size();
7064 s.insert(std::string((*it)->getName()));
7067 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7068 throw INTERP_KERNEL::Exception(oss.str().c_str());
7073 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7078 _nb_iter=ms->getNumberOfMeshes();
7082 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7086 MEDFileMesh *MEDFileMeshesIterator::nextt()
7088 if(_iter_id<_nb_iter)
7090 MEDFileMeshes *ms(_ms);
7092 return ms->getMeshAtPos(_iter_id++);