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::map<std::string, int>::const_iterator it=_families.find(name);
1436 if(it==_families.end())
1438 std::vector<std::string> fams(getFamiliesNames());
1439 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1440 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1441 throw INTERP_KERNEL::Exception(oss.str().c_str());
1443 return (*it).second;
1447 * Returns ids of the families having given names.
1448 * \param [in] fams - a sequence of the names of families of interest.
1449 * \return std::vector<int> - a sequence of the ids of families of interest.
1450 * \throw If \a fams contains a name of an inexistent family.
1452 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1454 std::vector<int> ret(fams.size());
1456 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1458 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1459 if(it2==_families.end())
1461 std::vector<std::string> fams2=getFamiliesNames();
1462 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1463 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1464 throw INTERP_KERNEL::Exception(oss.str().c_str());
1466 ret[i]=(*it2).second;
1472 * Returns a maximal abs(id) of families in \a this mesh.
1473 * \return int - the maximal norm of family id.
1474 * \throw If there are no families in \a this mesh.
1476 int MEDFileMesh::getMaxAbsFamilyId() const
1478 if(_families.empty())
1479 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1480 int ret=-std::numeric_limits<int>::max();
1481 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1483 ret=std::max(std::abs((*it).second),ret);
1489 * Returns a maximal id of families in \a this mesh.
1490 * \return int - the maximal family id.
1491 * \throw If there are no families in \a this mesh.
1493 int MEDFileMesh::getMaxFamilyId() const
1495 if(_families.empty())
1496 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1497 int ret=-std::numeric_limits<int>::max();
1498 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1500 ret=std::max((*it).second,ret);
1506 * Returns a minimal id of families in \a this mesh.
1507 * \return int - the minimal family id.
1508 * \throw If there are no families in \a this mesh.
1510 int MEDFileMesh::getMinFamilyId() const
1512 if(_families.empty())
1513 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1514 int ret=std::numeric_limits<int>::max();
1515 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1517 ret=std::min((*it).second,ret);
1523 * Returns a maximal id of families in \a this mesh. Not only named families are
1524 * considered but all family fields as well.
1525 * \return int - the maximal family id.
1527 int MEDFileMesh::getTheMaxAbsFamilyId() const
1529 int m1=-std::numeric_limits<int>::max();
1530 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1531 m1=std::max(std::abs((*it).second),m1);
1532 int m2=getMaxAbsFamilyIdInArrays();
1533 return std::max(m1,m2);
1537 * Returns a maximal id of families in \a this mesh. Not only named families are
1538 * considered but all family fields as well.
1539 * \return int - the maximal family id.
1541 int MEDFileMesh::getTheMaxFamilyId() const
1543 int m1=-std::numeric_limits<int>::max();
1544 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1545 m1=std::max((*it).second,m1);
1546 int m2=getMaxFamilyIdInArrays();
1547 return std::max(m1,m2);
1551 * Returns a minimal id of families in \a this mesh. Not only named families are
1552 * considered but all family fields as well.
1553 * \return int - the minimal family id.
1555 int MEDFileMesh::getTheMinFamilyId() const
1557 int m1=std::numeric_limits<int>::max();
1558 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1559 m1=std::min((*it).second,m1);
1560 int m2=getMinFamilyIdInArrays();
1561 return std::min(m1,m2);
1565 * This method only considers the maps. The contain of family array is ignored here.
1567 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1569 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1571 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1573 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1574 v.insert((*it).second);
1575 ret->alloc((int)v.size(),1);
1576 std::copy(v.begin(),v.end(),ret->getPointer());
1581 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1583 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1585 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1587 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1588 MCAuto<DataArrayInt> ret;
1589 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1591 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1592 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1593 if((DataArrayInt *) ret)
1594 ret=dv->buildUnion(ret);
1602 * true is returned if no modification has been needed. false if family
1603 * renumbering has been needed.
1605 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1607 std::vector<int> levs=getNonEmptyLevelsExt();
1608 std::set<int> allFamIds;
1609 int maxId=getMaxFamilyId()+1;
1610 std::map<int,std::vector<int> > famIdsToRenum;
1611 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1613 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1616 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1618 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1620 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1622 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1625 if(famIdsToRenum.empty())
1627 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1628 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1630 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1631 int *famIdsToChange=fam->getPointer();
1632 std::map<int,int> ren;
1633 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1635 if(allIds->presenceOfValue(*it3))
1637 std::string famName=getFamilyNameGivenId(*it3);
1638 std::vector<std::string> grps=getGroupsOnFamily(famName);
1641 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1642 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1643 addFamilyOnGrp((*it4),newFam);
1646 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1647 for(const int *id=ids->begin();id!=ids->end();id++)
1648 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1654 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1655 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1656 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1657 * This method will throw an exception if a same family id is detected in different level.
1658 * \warning This policy is the opposite of those in MED file documentation ...
1660 void MEDFileMesh::normalizeFamIdsTrio()
1662 ensureDifferentFamIdsPerLevel();
1663 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1664 std::vector<int> levs=getNonEmptyLevelsExt();
1665 std::set<int> levsS(levs.begin(),levs.end());
1666 std::set<std::string> famsFetched;
1667 std::map<std::string,int> families;
1668 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1671 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1675 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1676 std::map<int,int> ren;
1677 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1679 int nbOfTuples=fam->getNumberOfTuples();
1680 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1681 for(int *w=start;w!=start+nbOfTuples;w++)
1683 for(const int *it=tmp->begin();it!=tmp->end();it++)
1685 if(allIds->presenceOfValue(*it))
1687 std::string famName=getFamilyNameGivenId(*it);
1688 families[famName]=ren[*it];
1689 famsFetched.insert(famName);
1694 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1697 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1701 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1702 std::map<int,int> ren;
1703 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1705 int nbOfTuples=fam->getNumberOfTuples();
1706 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1707 for(int *w=start;w!=start+nbOfTuples;w++)
1709 for(const int *it=tmp->begin();it!=tmp->end();it++)
1711 if(allIds->presenceOfValue(*it))
1713 std::string famName=getFamilyNameGivenId(*it);
1714 families[famName]=ren[*it];
1715 famsFetched.insert(famName);
1720 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1722 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1725 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1726 fam->fillWithZero();
1727 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1728 if(allIds->presenceOfValue(*it3))
1730 std::string famName=getFamilyNameGivenId(*it3);
1731 families[famName]=0;
1732 famsFetched.insert(famName);
1737 std::vector<std::string> allFams=getFamiliesNames();
1738 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1739 std::set<std::string> unFetchedIds;
1740 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1741 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1742 families[*it4]=_families[*it4];
1747 * This method normalizes fam id with the following policy.
1748 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1749 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1750 * This method will throw an exception if a same family id is detected in different level.
1752 void MEDFileMesh::normalizeFamIdsMEDFile()
1754 ensureDifferentFamIdsPerLevel();
1755 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1756 std::vector<int> levs=getNonEmptyLevelsExt();
1757 std::set<int> levsS(levs.begin(),levs.end());
1758 std::set<std::string> famsFetched;
1759 std::map<std::string,int> families;
1761 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1764 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1767 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1768 std::map<int,int> ren;
1769 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1771 int nbOfTuples=fam->getNumberOfTuples();
1772 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1773 for(int *w=start;w!=start+nbOfTuples;w++)
1775 for(const int *it=tmp->begin();it!=tmp->end();it++)
1777 if(allIds->presenceOfValue(*it))
1779 std::string famName=getFamilyNameGivenId(*it);
1780 families[famName]=ren[*it];
1781 famsFetched.insert(famName);
1787 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1789 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1792 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1793 std::map<int,int> ren;
1794 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1796 int nbOfTuples=fam->getNumberOfTuples();
1797 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1798 for(int *w=start;w!=start+nbOfTuples;w++)
1800 for(const int *it=tmp->begin();it!=tmp->end();it++)
1802 if(allIds->presenceOfValue(*it))
1804 std::string famName=getFamilyNameGivenId(*it);
1805 families[famName]=ren[*it];
1806 famsFetched.insert(famName);
1812 std::vector<std::string> allFams=getFamiliesNames();
1813 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1814 std::set<std::string> unFetchedIds;
1815 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1816 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1817 families[*it4]=_families[*it4];
1822 * Returns a name of the family by its id. If there are several families having the given
1823 * id, the name first in lexical order is returned.
1824 * \param [in] id - the id of the family whose name is required.
1825 * \return std::string - the name of the found family.
1826 * \throw If no family with the given \a id exists.
1828 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1830 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1831 if((*it).second==id)
1833 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1834 throw INTERP_KERNEL::Exception(oss.str().c_str());
1838 * Returns a string describing \a this mesh. This description includes the mesh name and
1839 * the mesh description string.
1840 * \return std::string - the mesh information string.
1842 std::string MEDFileMesh::simpleRepr() const
1844 std::ostringstream oss;
1845 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1846 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1847 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1852 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1853 * an empty one is created.
1855 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1857 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1860 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1861 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1862 arr->fillWithZero();
1863 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1864 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1868 * Returns ids of mesh entities contained in a given group of a given dimension.
1869 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1871 * \param [in] grp - the name of the group of interest.
1872 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1873 * returned instead of ids.
1874 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1875 * numbers, if available and required, of mesh entities of the group. The caller
1876 * is to delete this array using decrRef() as it is no more needed.
1877 * \throw If the name of a nonexistent group is specified.
1878 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1880 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1882 std::vector<std::string> tmp(1);
1884 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1890 * Returns ids of mesh entities contained in given groups of a given dimension.
1891 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1893 * \param [in] grps - the names of the groups of interest.
1894 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1895 * returned instead of ids.
1896 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1897 * numbers, if available and required, of mesh entities of the groups. The caller
1898 * is to delete this array using decrRef() as it is no more needed.
1899 * \throw If the name of a nonexistent group is present in \a grps.
1900 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1902 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1904 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1905 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1909 * Returns ids of mesh entities contained in a given family of a given dimension.
1910 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1912 * \param [in] fam - the name of the family of interest.
1913 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1914 * returned instead of ids.
1915 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1916 * numbers, if available and required, of mesh entities of the family. The caller
1917 * is to delete this array using decrRef() as it is no more needed.
1918 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1920 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1922 std::vector<std::string> tmp(1);
1924 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1930 * Returns ids of nodes contained in a given group.
1931 * \param [in] grp - the name of the group of interest.
1932 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1933 * returned instead of ids.
1934 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1935 * numbers, if available and required, of nodes of the group. The caller
1936 * is to delete this array using decrRef() as it is no more needed.
1937 * \throw If the name of a nonexistent group is specified.
1938 * \throw If the family field is missing for nodes.
1940 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1942 std::vector<std::string> tmp(1);
1944 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1950 * Returns ids of nodes contained in given groups.
1951 * \param [in] grps - the names of the groups of interest.
1952 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1953 * returned instead of ids.
1954 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1955 * numbers, if available and required, of nodes of the groups. The caller
1956 * is to delete this array using decrRef() as it is no more needed.
1957 * \throw If the name of a nonexistent group is present in \a grps.
1958 * \throw If the family field is missing for nodes.
1960 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1962 return getGroupsArr(1,grps,renum);
1966 * Returns ids of nodes contained in a given group.
1967 * \param [in] grp - the name of the group of interest.
1968 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1969 * returned instead of ids.
1970 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1971 * numbers, if available and required, of nodes of the group. The caller
1972 * is to delete this array using decrRef() as it is no more needed.
1973 * \throw If the name of a nonexistent group is specified.
1974 * \throw If the family field is missing for nodes.
1976 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1978 std::vector<std::string> tmp(1);
1980 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1986 * Returns ids of nodes contained in given families.
1987 * \param [in] fams - the names of the families of interest.
1988 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1989 * returned instead of ids.
1990 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1991 * numbers, if available and required, of nodes of the families. The caller
1992 * is to delete this array using decrRef() as it is no more needed.
1993 * \throw If the family field is missing for nodes.
1995 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1997 return getFamiliesArr(1,fams,renum);
2001 * Adds groups of given dimension and creates corresponding families and family fields
2002 * given ids of mesh entities of each group.
2003 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2004 * \param [in] grps - a sequence of arrays of ids each describing a group.
2005 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2007 * \throw If names of some groups in \a grps are equal.
2008 * \throw If \a grps includes a group with an empty name.
2009 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2010 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2012 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2016 std::set<std::string> grpsName;
2017 std::vector<std::string> grpsName2(grps.size());
2020 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2022 grpsName.insert((*it)->getName());
2023 grpsName2[i]=(*it)->getName();
2025 if(grpsName.size()!=grps.size())
2026 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2027 if(grpsName.find(std::string(""))!=grpsName.end())
2028 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2029 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2030 MCAuto<DataArrayInt> fam;
2031 std::vector< std::vector<int> > fidsOfGroups;
2034 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2038 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2039 for(unsigned int ii=0;ii<grps.size();ii++)
2041 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2042 grps2[ii]->setName(grps[ii]->getName());
2044 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2045 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2048 if(!_families.empty())
2049 offset=getMaxAbsFamilyId()+1;
2050 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2051 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2052 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2053 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2057 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2058 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2059 * For the moment, the two last input parameters are not taken into account.
2061 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2063 std::map<int,std::string> famInv;
2064 for(const int *it=famIds->begin();it!=famIds->end();it++)
2066 std::ostringstream oss;
2067 oss << "Family_" << (*it);
2068 _families[oss.str()]=(*it);
2069 famInv[*it]=oss.str();
2072 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2074 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2076 _groups[grpNames[i]].push_back(famInv[*it2]);
2081 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2083 std::vector<int> levs(getNonEmptyLevels());
2084 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2085 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2087 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2088 ret.insert(ret.end(),elts.begin(),elts.end());
2093 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2095 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2096 return mLev->getDistributionOfTypes();
2099 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2101 loadLL(fid,mName,dt,it,mrs);
2102 loadJointsFromFile(fid);
2103 loadEquivalences(fid);
2106 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2108 famArr->applyLin(offset>0?1:-1,offset,0);
2109 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2112 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2113 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2118 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2119 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2120 * If this method fails to find such a name it will throw an exception.
2122 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2125 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2128 std::size_t len=nameTry.length();
2129 for(std::size_t ii=1;ii<len;ii++)
2131 std::string tmp=nameTry.substr(ii,len-ii);
2132 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2138 for(std::size_t i=1;i<30;i++)
2140 std::string tmp1(nameTry.at(0),i);
2142 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2148 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2150 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2152 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2155 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2157 std::size_t nbOfChunks=code.size()/3;
2158 if(code.size()%3!=0)
2159 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2161 for(std::size_t i=0;i<nbOfChunks;i++)
2170 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2171 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2172 * If _name is not empty and that 'm' has the same name nothing is done.
2173 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2175 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2178 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2183 std::string name(m->getName());
2188 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2189 oss << name << "' ! Names must match !";
2190 throw INTERP_KERNEL::Exception(oss.str().c_str());
2194 if(_desc_name.empty())
2195 _desc_name=m->getDescription();
2198 std::string name(m->getDescription());
2201 if(_desc_name!=name)
2203 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2204 oss << name << "' ! Names must match !";
2205 throw INTERP_KERNEL::Exception(oss.str().c_str());
2211 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2213 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2214 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2216 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2217 oss << " - Groups lying on this family : ";
2218 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2219 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2220 oss << std::endl << std::endl;
2225 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2226 * file. The mesh to load is specified by its name and numbers of a time step and an
2228 * \param [in] fileName - the name of MED file to read.
2229 * \param [in] mName - the name of the mesh to read.
2230 * \param [in] dt - the number of a time step.
2231 * \param [in] it - the number of an iteration.
2232 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2233 * mesh using decrRef() as it is no more needed.
2234 * \throw If the file is not readable.
2235 * \throw If there is no mesh with given attributes in the file.
2236 * \throw If the mesh in the file is not an unstructured one.
2238 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2240 MEDFileUtilities::CheckFileForRead(fileName);
2241 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2242 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2246 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2247 * file. The first mesh in the file is loaded.
2248 * \param [in] fileName - the name of MED file to read.
2249 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2250 * mesh using decrRef() as it is no more needed.
2251 * \throw If the file is not readable.
2252 * \throw If there is no meshes in the file.
2253 * \throw If the mesh in the file is not an unstructured one.
2255 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2257 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
2260 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2261 throw INTERP_KERNEL::Exception(oss.str().c_str());
2263 MEDFileUtilities::CheckFileForRead(fileName);
2264 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2266 MEDCoupling::MEDCouplingMeshType meshType;
2268 MEDCoupling::MEDCouplingAxisType dummy3;
2269 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2270 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2274 * Returns an empty instance of MEDFileUMesh.
2275 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2276 * mesh using decrRef() as it is no more needed.
2278 MEDFileUMesh *MEDFileUMesh::New()
2280 return new MEDFileUMesh;
2284 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2285 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2286 * \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.
2287 * 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
2288 * at most the memory consumtion.
2290 * \param [in] fileName - the name of the file.
2291 * \param [in] mName - the name of the mesh to be read.
2292 * \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.
2293 * \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.
2294 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2295 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2296 * \param [in] mrs - the request for what to be loaded.
2297 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2299 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)
2301 MEDFileUtilities::CheckFileForRead(fileName);
2302 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2303 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2307 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2308 * This method is \b NOT wrapped into python.
2310 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)
2312 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2313 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2317 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2319 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2320 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>));
2324 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2326 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2327 ret.push_back((const DataArrayDouble*)_coords);
2328 ret.push_back((const DataArrayInt *)_fam_coords);
2329 ret.push_back((const DataArrayInt *)_num_coords);
2330 ret.push_back((const DataArrayInt *)_rev_num_coords);
2331 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2332 ret.push_back((const PartDefinition *)_part_coords);
2333 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2334 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2338 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2340 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2344 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2346 return new MEDFileUMesh;
2349 MEDFileMesh *MEDFileUMesh::deepCopy() const
2351 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2352 ret->deepCpyEquivalences(*this);
2353 if((const DataArrayDouble*)_coords)
2354 ret->_coords=_coords->deepCopy();
2355 if((const DataArrayInt*)_fam_coords)
2356 ret->_fam_coords=_fam_coords->deepCopy();
2357 if((const DataArrayInt*)_num_coords)
2358 ret->_num_coords=_num_coords->deepCopy();
2359 if((const DataArrayInt*)_rev_num_coords)
2360 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2361 if((const DataArrayAsciiChar*)_name_coords)
2362 ret->_name_coords=_name_coords->deepCopy();
2364 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2366 if((const MEDFileUMeshSplitL1 *)(*it))
2367 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2369 if((const PartDefinition*)_part_coords)
2370 ret->_part_coords=_part_coords->deepCopy();
2375 * Checks if \a this and another mesh are equal.
2376 * \param [in] other - the mesh to compare with.
2377 * \param [in] eps - a precision used to compare real values.
2378 * \param [in,out] what - the string returning description of unequal data.
2379 * \return bool - \c true if the meshes are equal, \c false, else.
2381 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2383 if(!MEDFileMesh::isEqual(other,eps,what))
2385 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2388 what="Mesh types differ ! This is unstructured and other is NOT !";
2391 clearNonDiscrAttributes();
2392 otherC->clearNonDiscrAttributes();
2393 const DataArrayDouble *coo1=_coords;
2394 const DataArrayDouble *coo2=otherC->_coords;
2395 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2397 what="Mismatch of coordinates ! One is defined and not other !";
2402 bool ret=coo1->isEqual(*coo2,eps);
2405 what="Coords differ !";
2409 const DataArrayInt *famc1=_fam_coords;
2410 const DataArrayInt *famc2=otherC->_fam_coords;
2411 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2413 what="Mismatch of families arr on nodes ! One is defined and not other !";
2418 bool ret=famc1->isEqual(*famc2);
2421 what="Families arr on node differ !";
2425 const DataArrayInt *numc1=_num_coords;
2426 const DataArrayInt *numc2=otherC->_num_coords;
2427 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2429 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2434 bool ret=numc1->isEqual(*numc2);
2437 what="Numbering arr on node differ !";
2441 const DataArrayAsciiChar *namec1=_name_coords;
2442 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2443 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2445 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2450 bool ret=namec1->isEqual(*namec2);
2453 what="Names arr on node differ !";
2457 if(_ms.size()!=otherC->_ms.size())
2459 what="Number of levels differs !";
2462 std::size_t sz=_ms.size();
2463 for(std::size_t i=0;i<sz;i++)
2465 const MEDFileUMeshSplitL1 *s1=_ms[i];
2466 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2467 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2469 what="Mismatch of presence of sub levels !";
2474 bool ret=s1->isEqual(s2,eps,what);
2479 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2482 if((!pd0 && pd1) || (pd0 && !pd1))
2484 what=std::string("node part def is defined only for one among this or other !");
2487 return pd0->isEqual(pd1,what);
2491 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2492 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2493 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2494 * \throw if internal family array is inconsistent
2495 * \sa checkSMESHConsistency()
2497 void MEDFileUMesh::checkConsistency() const
2499 if(!_coords || !_coords->isAllocated())
2502 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2504 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2505 if (!_num_coords || !_rev_num_coords)
2506 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2510 int nbCoo = _coords->getNumberOfTuples();
2512 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2515 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2517 int maxValue=_num_coords->getMaxValue(pos);
2518 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2519 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2521 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2522 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2523 if (_num_coords && !_num_coords->hasUniqueValues())
2524 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2526 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2527 // Now sub part check:
2528 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2529 it != _ms.end(); it++)
2530 (*it)->checkConsistency();
2535 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2536 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2537 * entities as it likes), or non overlapping between all sub-levels.
2538 * \throw if the condition above is not respected
2540 void MEDFileUMesh::checkSMESHConsistency() const
2543 // For all sub-levels, numbering is either always null or with void intersection:
2546 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2547 std::vector< const DataArrayInt * > v;
2548 bool voidOrNot = ((*it)->_num == 0);
2549 for (it++; it != _ms.end(); it++)
2550 if( ((*it)->_num == 0) != voidOrNot )
2551 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2552 else if (!voidOrNot)
2553 v.push_back((*it)->_num);
2556 // don't forget the 1st one:
2557 v.push_back(_ms[0]->_num);
2558 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2559 if (inter->getNumberOfTuples())
2560 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2566 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2567 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2569 void MEDFileUMesh::clearNodeAndCellNumbers()
2572 _rev_num_coords = 0;
2573 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2574 it != _ms.end(); it++)
2577 (*it)->_rev_num = 0;
2582 * Clears redundant attributes of incorporated data arrays.
2584 void MEDFileUMesh::clearNonDiscrAttributes() const
2586 MEDFileMesh::clearNonDiscrAttributes();
2587 const DataArrayDouble *coo1=_coords;
2589 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2590 const DataArrayInt *famc1=_fam_coords;
2592 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2593 const DataArrayInt *numc1=_num_coords;
2595 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2596 const DataArrayAsciiChar *namc1=_name_coords;
2598 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2599 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2601 const MEDFileUMeshSplitL1 *tmp=(*it);
2603 tmp->clearNonDiscrAttributes();
2607 void MEDFileUMesh::setName(const std::string& name)
2609 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2610 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2611 (*it)->setName(name);
2612 MEDFileMesh::setName(name);
2615 MEDFileUMesh::MEDFileUMesh()
2619 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2622 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2624 catch(INTERP_KERNEL::Exception& e)
2630 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2631 * See MEDFileUMesh::LoadPartOf for detailed description.
2635 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)
2637 MEDFileUMeshL2 loaderl2;
2638 MEDCoupling::MEDCouplingMeshType meshType;
2641 MEDCoupling::MEDCouplingAxisType dummy3;
2642 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2643 if(meshType!=UNSTRUCTURED)
2645 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2646 throw INTERP_KERNEL::Exception(oss.str().c_str());
2648 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2649 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2653 * \brief Write joints in a file
2655 void MEDFileMesh::writeJoints(med_idt fid) const
2657 if ( (const MEDFileJoints*) _joints )
2658 _joints->write(fid);
2662 * \brief Load joints in a file or use provided ones
2664 //================================================================================
2666 * \brief Load joints in a file or use provided ones
2667 * \param [in] fid - MED file descriptor
2668 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2669 * Usually this joints are those just read by another iteration
2670 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2672 //================================================================================
2674 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2676 if ( toUseInstedOfReading )
2677 setJoints( toUseInstedOfReading );
2679 _joints = MEDFileJoints::New( fid, _name );
2682 void MEDFileMesh::loadEquivalences(med_idt fid)
2684 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2686 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2689 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2691 const MEDFileEquivalences *equiv(other._equiv);
2693 _equiv=equiv->deepCopy(this);
2696 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2698 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2699 if(!thisEq && !otherEq)
2701 if(thisEq && otherEq)
2702 return thisEq->isEqual(otherEq,what);
2705 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2710 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2712 const MEDFileEquivalences *equiv(_equiv);
2715 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2716 _equiv->getRepr(oss);
2719 void MEDFileMesh::checkCartesian() const
2721 if(getAxisType()!=AX_CART)
2723 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()) << ").";
2724 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2725 oss << " - call setAxisType(AX_CART)" << std::endl;
2726 oss << " - call cartesianize()";
2727 throw INTERP_KERNEL::Exception(oss.str().c_str());
2732 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2734 int MEDFileMesh::getNumberOfJoints() const
2736 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2740 * \brief Return joints with all adjacent mesh domains
2742 MEDFileJoints * MEDFileMesh::getJoints() const
2744 return const_cast<MEDFileJoints*>(& (*_joints));
2747 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2749 if ( joints != _joints )
2758 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2760 * \sa loadPartUMeshFromFile
2762 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2764 MEDFileUMeshL2 loaderl2;
2765 MEDCoupling::MEDCouplingMeshType meshType;
2768 MEDCoupling::MEDCouplingAxisType axType;
2769 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2770 setAxisType(axType);
2771 if(meshType!=UNSTRUCTURED)
2773 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2774 throw INTERP_KERNEL::Exception(oss.str().c_str());
2776 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2777 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2780 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2782 int lev=loaderl2.getNumberOfLevels();
2784 for(int i=0;i<lev;i++)
2786 if(!loaderl2.emptyLev(i))
2787 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2791 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2793 setName(loaderl2.getName());
2794 setDescription(loaderl2.getDescription());
2795 setUnivName(loaderl2.getUnivName());
2796 setIteration(loaderl2.getIteration());
2797 setOrder(loaderl2.getOrder());
2798 setTimeValue(loaderl2.getTime());
2799 setTimeUnit(loaderl2.getTimeUnit());
2800 _coords=loaderl2.getCoords();
2801 if(!mrs || mrs->isNodeFamilyFieldReading())
2802 _fam_coords=loaderl2.getCoordsFamily();
2803 if(!mrs || mrs->isNodeNumFieldReading())
2804 _num_coords=loaderl2.getCoordsNum();
2805 if(!mrs || mrs->isNodeNameFieldReading())
2806 _name_coords=loaderl2.getCoordsName();
2807 _part_coords=loaderl2.getPartDefOfCoo();
2811 MEDFileUMesh::~MEDFileUMesh()
2815 void MEDFileUMesh::writeLL(med_idt fid) const
2817 const DataArrayDouble *coo=_coords;
2818 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2819 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2820 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2821 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2822 int spaceDim=coo?coo->getNumberOfComponents():0;
2825 mdim=getMeshDimension();
2826 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2827 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2828 for(int i=0;i<spaceDim;i++)
2830 std::string info=coo->getInfoOnComponent(i);
2832 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2833 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
2834 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
2836 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2838 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2839 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2840 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2841 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2842 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2843 (*it)->write(fid,meshName,mdim);
2844 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2848 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2849 * \return std::vector<int> - a sequence of the relative dimensions.
2851 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2853 std::vector<int> ret;
2855 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2856 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2863 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2864 * \return std::vector<int> - a sequence of the relative dimensions.
2866 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2868 std::vector<int> ret0=getNonEmptyLevels();
2869 if((const DataArrayDouble *) _coords)
2871 std::vector<int> ret(ret0.size()+1);
2873 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2879 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2881 std::vector<int> ret;
2882 const DataArrayInt *famCoo(_fam_coords);
2886 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2888 const MEDFileUMeshSplitL1 *cur(*it);
2890 if(cur->getFamilyField())
2896 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2898 std::vector<int> ret;
2899 const DataArrayInt *numCoo(_num_coords);
2903 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2905 const MEDFileUMeshSplitL1 *cur(*it);
2907 if(cur->getNumberField())
2913 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2915 std::vector<int> ret;
2916 const DataArrayAsciiChar *nameCoo(_name_coords);
2920 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2922 const MEDFileUMeshSplitL1 *cur(*it);
2924 if(cur->getNameField())
2931 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2932 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2933 * \param [in] fams - the name of the family of interest.
2934 * \return std::vector<int> - a sequence of the relative dimensions.
2936 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2938 std::vector<int> ret;
2939 std::vector<int> levs(getNonEmptyLevels());
2940 std::vector<int> famIds(getFamiliesIds(fams));
2941 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2942 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2948 * Returns all relative mesh levels (including nodes) where given families are defined.
2949 * \param [in] fams - the names of the families of interest.
2950 * \return std::vector<int> - a sequence of the relative dimensions.
2952 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2954 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2955 const DataArrayInt *famCoords(_fam_coords);
2958 std::vector<int> famIds(getFamiliesIds(fams));
2959 if(famCoords->presenceOfValue(famIds))
2961 std::vector<int> ret(ret0.size()+1);
2963 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2970 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2972 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2973 if((const DataArrayInt *)_fam_coords)
2975 int val=_fam_coords->getMaxValue(tmp);
2976 ret=std::max(ret,std::abs(val));
2978 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2980 if((const MEDFileUMeshSplitL1 *)(*it))
2982 const DataArrayInt *da=(*it)->getFamilyField();
2985 int val=da->getMaxValue(tmp);
2986 ret=std::max(ret,std::abs(val));
2993 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2995 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2996 if((const DataArrayInt *)_fam_coords)
2998 int val=_fam_coords->getMaxValue(tmp);
2999 ret=std::max(ret,val);
3001 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3003 if((const MEDFileUMeshSplitL1 *)(*it))
3005 const DataArrayInt *da=(*it)->getFamilyField();
3008 int val=da->getMaxValue(tmp);
3009 ret=std::max(ret,val);
3016 int MEDFileUMesh::getMinFamilyIdInArrays() const
3018 int ret=std::numeric_limits<int>::max(),tmp=-1;
3019 if((const DataArrayInt *)_fam_coords)
3021 int val=_fam_coords->getMinValue(tmp);
3022 ret=std::min(ret,val);
3024 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3026 if((const MEDFileUMeshSplitL1 *)(*it))
3028 const DataArrayInt *da=(*it)->getFamilyField();
3031 int val=da->getMinValue(tmp);
3032 ret=std::min(ret,val);
3040 * Returns the dimension on cells in \a this mesh.
3041 * \return int - the mesh dimension.
3042 * \throw If there are no cells in this mesh.
3044 int MEDFileUMesh::getMeshDimension() const
3047 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3048 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3049 return (*it)->getMeshDimension()+lev;
3050 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3054 * Returns the space dimension of \a this mesh that is equal to number of components in
3055 * the node coordinates array.
3056 * \return int - the space dimension of \a this mesh.
3057 * \throw If the node coordinates array is not available.
3059 int MEDFileUMesh::getSpaceDimension() const
3061 const DataArrayDouble *coo=_coords;
3063 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3064 return coo->getNumberOfComponents();
3068 * Returns a string describing \a this mesh.
3069 * \return std::string - the mesh information string.
3071 std::string MEDFileUMesh::simpleRepr() const
3073 std::ostringstream oss;
3074 oss << MEDFileMesh::simpleRepr();
3075 const DataArrayDouble *coo=_coords;
3076 oss << "- The dimension of the space is ";
3077 static const char MSG1[]= "*** NO COORDS SET ***";
3078 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3080 oss << _coords->getNumberOfComponents() << std::endl;
3082 oss << MSG1 << std::endl;
3083 oss << "- Type of the mesh : UNSTRUCTURED\n";
3084 oss << "- Number of nodes : ";
3086 oss << _coords->getNumberOfTuples() << std::endl;
3088 oss << MSG1 << std::endl;
3089 std::size_t nbOfLev=_ms.size();
3090 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3091 for(std::size_t i=0;i<nbOfLev;i++)
3093 const MEDFileUMeshSplitL1 *lev=_ms[i];
3094 oss << " - Level #" << -((int) i) << " has dimension : ";
3097 oss << lev->getMeshDimension() << std::endl;
3098 lev->simpleRepr(oss);
3101 oss << MSG2 << std::endl;
3103 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3106 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3107 oss << "- Names of coordinates :" << std::endl;
3108 std::vector<std::string> vars=coo->getVarsOnComponent();
3109 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3110 oss << std::endl << "- Units of coordinates : " << std::endl;
3111 std::vector<std::string> units=coo->getUnitsOnComponent();
3112 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3114 oss << std::endl << std::endl;
3116 getEquivalencesRepr(oss);
3121 * Returns a full textual description of \a this mesh.
3122 * \return std::string - the string holding the mesh description.
3124 std::string MEDFileUMesh::advancedRepr() const
3126 return simpleRepr();
3130 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3131 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3132 * \return int - the number of entities.
3133 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3135 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3137 if(meshDimRelToMaxExt==1)
3139 if(!((const DataArrayDouble *)_coords))
3140 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3141 return _coords->getNumberOfTuples();
3143 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3147 * Returns the family field for mesh entities of a given dimension.
3148 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3149 * \return const DataArrayInt * - the family field. It is an array of ids of families
3150 * each mesh entity belongs to. It can be \c NULL.
3152 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3154 if(meshDimRelToMaxExt==1)
3156 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3157 return l1->getFamilyField();
3160 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3162 if(meshDimRelToMaxExt==1)
3164 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3165 return l1->getFamilyField();
3169 * Returns the optional numbers of mesh entities of a given dimension.
3170 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3171 * \return const DataArrayInt * - the array of the entity numbers.
3172 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3174 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3176 if(meshDimRelToMaxExt==1)
3178 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3179 return l1->getNumberField();
3182 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3184 if(meshDimRelToMaxExt==1)
3185 return _name_coords;
3186 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3187 return l1->getNameField();
3191 * 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).
3193 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3194 * \param [in] gt - The input geometric type for which the part definition is requested.
3195 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3197 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3199 if(meshDimRelToMaxExt==1)
3200 return _part_coords;
3201 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3202 return l1->getPartDef(gt);
3205 int MEDFileUMesh::getNumberOfNodes() const
3207 const DataArrayDouble *coo(_coords);
3209 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3210 return coo->getNumberOfTuples();
3213 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3215 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3216 return l1->getNumberOfCells();
3219 bool MEDFileUMesh::hasImplicitPart() const
3224 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3226 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3229 void MEDFileUMesh::releaseImplicitPartIfAny() const
3233 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3235 std::size_t sz(st.getNumberOfItems());
3236 for(std::size_t i=0;i<sz;i++)
3238 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3239 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3240 if(st[i].getPflName().empty())
3241 m->computeNodeIdsAlg(nodesFetched);
3244 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3245 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3246 m2->computeNodeIdsAlg(nodesFetched);
3251 MEDFileMesh *MEDFileUMesh::cartesianize() const
3253 if(getAxisType()==AX_CART)
3256 return const_cast<MEDFileUMesh *>(this);
3260 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3261 const DataArrayDouble *coords(_coords);
3263 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3264 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3265 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3266 if((const MEDFileUMeshSplitL1 *)(*it))
3267 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3268 ret->_coords=coordsCart;
3269 ret->setAxisType(AX_CART);
3275 * Returns the optional numbers of mesh entities of a given dimension transformed using
3276 * DataArrayInt::invertArrayN2O2O2N().
3277 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3278 * \return const DataArrayInt * - the array of the entity numbers transformed using
3279 * DataArrayInt::invertArrayN2O2O2N().
3280 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3282 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3284 if(meshDimRelToMaxExt==1)
3286 if(!((const DataArrayInt *)_num_coords))
3287 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3288 return _rev_num_coords;
3290 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3291 return l1->getRevNumberField();
3295 * Returns a pointer to the node coordinates array of \a this mesh \b without
3296 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3298 DataArrayDouble *MEDFileUMesh::getCoords() const
3301 MCAuto<DataArrayDouble> tmp(_coords);
3302 if((DataArrayDouble *)tmp)
3310 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3311 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3313 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3314 * \param [in] grp - the name of the group whose mesh entities are included in the
3316 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3317 * according to the optional numbers of entities, if available.
3318 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3319 * delete this mesh using decrRef() as it is no more needed.
3320 * \throw If the name of a nonexistent group is specified.
3321 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3323 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3326 synchronizeTinyInfoOnLeaves();
3327 std::vector<std::string> tmp(1);
3329 return getGroups(meshDimRelToMaxExt,tmp,renum);
3333 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3334 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3336 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3337 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3339 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3340 * according to the optional numbers of entities, if available.
3341 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3342 * delete this mesh using decrRef() as it is no more needed.
3343 * \throw If a name of a nonexistent group is present in \a grps.
3344 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3346 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3349 synchronizeTinyInfoOnLeaves();
3350 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3351 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3352 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3353 zeRet->setName(grps[0]);
3354 return zeRet.retn();
3358 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3359 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3361 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3362 * \param [in] fam - the name of the family whose mesh entities are included in the
3364 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3365 * according to the optional numbers of entities, if available.
3366 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3367 * delete this mesh using decrRef() as it is no more needed.
3368 * \throw If a name of a nonexistent family is present in \a grps.
3369 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3371 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3374 synchronizeTinyInfoOnLeaves();
3375 std::vector<std::string> tmp(1);
3377 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3381 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3382 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3384 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3385 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3387 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3388 * according to the optional numbers of entities, if available.
3389 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3390 * delete this mesh using decrRef() as it is no more needed.
3391 * \throw If a name of a nonexistent family is present in \a fams.
3392 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3394 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3397 synchronizeTinyInfoOnLeaves();
3398 if(meshDimRelToMaxExt==1)
3400 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3401 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3402 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3406 std::vector<int> famIds=getFamiliesIds(fams);
3407 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3408 MCAuto<MEDCouplingUMesh> zeRet;
3410 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3412 zeRet=l1->getFamilyPart(0,0,renum);
3413 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3414 zeRet->setName(fams[0]);
3415 return zeRet.retn();
3419 * Returns ids of mesh entities contained in given families of a given dimension.
3420 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3422 * \param [in] fams - the names of the families of interest.
3423 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3424 * returned instead of ids.
3425 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3426 * numbers, if available and required, of mesh entities of the families. The caller
3427 * is to delete this array using decrRef() as it is no more needed.
3428 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3430 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3432 std::vector<int> famIds=getFamiliesIds(fams);
3433 if(meshDimRelToMaxExt==1)
3435 if((const DataArrayInt *)_fam_coords)
3437 MCAuto<DataArrayInt> da;
3439 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3441 da=_fam_coords->findIdsEqualList(0,0);
3443 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3448 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3450 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3452 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3454 return l1->getFamilyPartArr(0,0,renum);
3458 * Returns a MEDCouplingUMesh of a given relative dimension.
3459 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3460 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3461 * To build a valid MEDCouplingUMesh from the returned one in this case,
3462 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3463 * \param [in] meshDimRelToMax - the relative dimension of interest.
3464 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3465 * optional numbers of mesh entities.
3466 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3467 * delete using decrRef() as it is no more needed.
3468 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3470 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3473 synchronizeTinyInfoOnLeaves();
3474 if(meshDimRelToMaxExt==1)
3478 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3479 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3480 umesh->setCoords(cc);
3481 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3482 umesh->setName(getName());
3486 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3487 return l1->getWholeMesh(renum);
3490 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3492 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3493 return l1->getDistributionOfTypes();
3497 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3498 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3499 * optional numbers of mesh entities.
3500 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3501 * delete using decrRef() as it is no more needed.
3502 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3504 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3506 return getMeshAtLevel(0,renum);
3510 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3511 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3512 * optional numbers of mesh entities.
3513 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3514 * delete using decrRef() as it is no more needed.
3515 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3517 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3519 return getMeshAtLevel(-1,renum);
3523 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3524 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3525 * optional numbers of mesh entities.
3526 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3527 * delete using decrRef() as it is no more needed.
3528 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3530 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3532 return getMeshAtLevel(-2,renum);
3536 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3537 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3538 * optional numbers of mesh entities.
3539 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3540 * delete using decrRef() as it is no more needed.
3541 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3543 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3545 return getMeshAtLevel(-3,renum);
3549 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3550 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3551 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3552 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3554 void MEDFileUMesh::forceComputationOfParts() const
3556 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3558 const MEDFileUMeshSplitL1 *elt(*it);
3560 elt->forceComputationOfParts();
3565 * This method returns a vector of mesh parts containing each exactly one geometric type.
3566 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3567 * This method is only for memory aware users.
3568 * The returned pointers are **NOT** new object pointer. No need to mange them.
3570 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3573 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3574 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3578 * This method returns the part of \a this having the geometric type \a gt.
3579 * If such part is not existing an exception will be thrown.
3580 * The returned pointer is **NOT** new object pointer. No need to mange it.
3582 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3585 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3586 int lev=(int)cm.getDimension()-getMeshDimension();
3587 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3588 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3592 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3593 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3595 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3597 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3598 return sp->getGeoTypes();
3601 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3603 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3604 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3605 return sp->getNumberOfCellsWithType(ct);
3609 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3610 * \param [in] gt - the geometric type for which the family field is asked.
3611 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3612 * delete using decrRef() as it is no more needed.
3613 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3615 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3617 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3618 int lev=(int)cm.getDimension()-getMeshDimension();
3619 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3620 return sp->extractFamilyFieldOnGeoType(gt);
3624 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3625 * \param [in] gt - the geometric type for which the number field is asked.
3626 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3627 * delete using decrRef() as it is no more needed.
3628 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3630 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3632 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3633 int lev=(int)cm.getDimension()-getMeshDimension();
3634 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3635 return sp->extractNumberFieldOnGeoType(gt);
3639 * This method returns for specified geometric type \a gt the relative level to \a this.
3640 * If the relative level is empty an exception will be thrown.
3642 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3644 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3645 int ret((int)cm.getDimension()-getMeshDimension());
3646 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3650 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3652 if(meshDimRelToMaxExt==1)
3653 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3654 if(meshDimRelToMaxExt>1)
3655 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3656 int tracucedRk=-meshDimRelToMaxExt;
3657 if(tracucedRk>=(int)_ms.size())
3658 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3659 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3660 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3661 return _ms[tracucedRk];
3664 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3666 if(meshDimRelToMaxExt==1)
3667 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3668 if(meshDimRelToMaxExt>1)
3669 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3670 int tracucedRk=-meshDimRelToMaxExt;
3671 if(tracucedRk>=(int)_ms.size())
3672 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3673 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3674 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3675 return _ms[tracucedRk];
3678 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3680 if(-meshDimRelToMax>=(int)_ms.size())
3681 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3683 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3685 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3687 int ref=(*it)->getMeshDimension();
3688 if(ref+i!=meshDim-meshDimRelToMax)
3689 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3695 * Sets the node coordinates array of \a this mesh.
3696 * \param [in] coords - the new node coordinates array.
3697 * \throw If \a coords == \c NULL.
3699 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3702 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3703 if(coords==(DataArrayDouble *)_coords)
3705 coords->checkAllocated();
3706 int nbOfTuples=coords->getNumberOfTuples();
3709 _fam_coords=DataArrayInt::New();
3710 _fam_coords->alloc(nbOfTuples,1);
3711 _fam_coords->fillWithZero();
3712 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3713 if((MEDFileUMeshSplitL1 *)(*it))
3714 (*it)->setCoords(coords);
3718 * Removes all groups of a given dimension in \a this mesh.
3719 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3720 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3722 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3724 if(meshDimRelToMaxExt==1)
3726 if((DataArrayInt *)_fam_coords)
3727 _fam_coords->fillWithZero();
3730 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3731 l1->eraseFamilyField();
3736 * Removes all families with ids not present in the family fields of \a this mesh.
3738 void MEDFileUMesh::optimizeFamilies()
3740 std::vector<int> levs=getNonEmptyLevelsExt();
3741 std::set<int> allFamsIds;
3742 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3744 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3745 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3747 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3750 std::set<std::string> famNamesToKill;
3751 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3753 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3754 famNamesToKill.insert((*it).first);
3756 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3757 _families.erase(*it);
3758 std::vector<std::string> grpNamesToKill;
3759 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3761 std::vector<std::string> tmp;
3762 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3764 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3765 tmp.push_back(*it2);
3770 tmp.push_back((*it).first);
3772 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3777 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3778 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3779 * The boundary is built according to the following method:
3780 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3781 * coordinates array is extended).
3782 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3783 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3784 * might not be duplicated at all.
3785 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3786 * other side of the group is no more a neighbor)
3787 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3788 * bordering the newly created boundary use the newly computed nodes.
3789 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3790 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3792 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3793 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3795 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3796 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3797 * \sa clearNodeAndCellNumbers()
3799 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3800 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3802 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3803 typedef MCAuto<DataArrayInt> DAInt;
3805 std::vector<int> levs=getNonEmptyLevels();
3806 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3807 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3808 MUMesh m0=getMeshAtLevel(0);
3809 MUMesh m1=getMeshAtLevel(-1);
3810 int nbNodes=m0->getNumberOfNodes();
3811 MUMesh m11=getGroup(-1,grpNameM1);
3812 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3813 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3814 DAInt nodeIdsToDuplicate(tmp00);
3815 DAInt cellsToModifyConn0(tmp11);
3816 DAInt cellsToModifyConn1(tmp22);
3817 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3818 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3819 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3820 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3821 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3822 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3823 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3824 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3825 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3826 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3827 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3828 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3829 DAInt grpIds=getGroupArr(-1,grpNameM1);
3830 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3831 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3832 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3833 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3834 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3835 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3836 m0->setCoords(tmp0->getCoords());
3837 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3838 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3839 m1->setCoords(m0->getCoords());
3840 _coords=m0->getCoords(); _coords->incrRef();
3841 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3842 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3843 DataArrayInt * duplCells;
3844 m1->areCellsIncludedIn(m11, 0, duplCells);
3845 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3846 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3847 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3848 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3849 DAInt szOfCellGrpOfSameType(tmp00);
3850 DAInt idInMsOfCellGrpOfSameType(tmp11);
3852 newm1->setName(getName());
3853 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3855 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3856 DAInt newFam=DataArrayInt::New();
3857 newFam->alloc(newm1->getNumberOfCells(),1);
3858 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3859 // Positive ID for family of nodes, negative for all the rest.
3861 if (m1->getMeshDimension() == 0)
3862 idd=getMaxFamilyId()+1;
3864 idd=getMinFamilyId()-1;
3865 int globStart=0,start=0,end,globEnd;
3866 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3867 for(int i=0;i<nbOfChunks;i++)
3869 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3870 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3872 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3873 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3874 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3879 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3883 newm1->setCoords(getCoords());
3884 setMeshAtLevel(-1,newm1);
3885 setFamilyFieldArr(-1,newFam);
3886 std::string grpName2(grpNameM1); grpName2+="_dup";
3887 addFamily(grpName2,idd);
3888 addFamilyOnGrp(grpName2,grpName2);
3893 int newNbOfNodes=getCoords()->getNumberOfTuples();
3894 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3895 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3896 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3901 _rev_num_coords = 0;
3902 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
3903 it != _ms.end(); it++)
3906 (*it)->_rev_num = 0;
3908 nodesDuplicated=nodeIdsToDuplicate.retn();
3909 cellsModified=cellsToModifyConn0.retn();
3910 cellsNotModified=cellsToModifyConn1.retn();
3913 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
3914 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
3917 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3918 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3919 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3921 * \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.
3922 * 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.
3924 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3926 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3927 std::vector<int> levs=getNonEmptyLevels();
3929 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3930 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3933 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3935 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3936 std::vector<int> code1=m->getDistributionOfTypes();
3937 end=PutInThirdComponentOfCodeOffset(code1,start);
3938 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3939 bool hasChanged=m->unPolyze();
3940 DataArrayInt *fake=0;
3941 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3942 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3944 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3947 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3948 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3950 MCAuto<DataArrayInt> famField2,numField2;
3951 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3952 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3953 setMeshAtLevel(*it,m);
3954 std::vector<int> code2=m->getDistributionOfTypes();
3955 end=PutInThirdComponentOfCodeOffset(code2,start);
3956 newCode.insert(newCode.end(),code2.begin(),code2.end());
3958 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
3962 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3963 setFamilyFieldArr(*it,newFamField);
3967 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3968 setRenumFieldArr(*it,newNumField);
3973 newCode.insert(newCode.end(),code1.begin(),code1.end());
3979 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3980 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3981 o2nRenumCell=o2nRenumCellRet.retn();
3986 /*! \cond HIDDEN_ITEMS */
3987 struct MEDLoaderAccVisit1
3989 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3990 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3991 int _new_nb_of_nodes;
3996 * 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.
3997 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3998 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3999 * -1 values in returned array means that the corresponding old node is no more used.
4001 * \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
4002 * is modified in \a this.
4003 * \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
4006 DataArrayInt *MEDFileUMesh::zipCoords()
4008 const DataArrayDouble *coo(getCoords());
4010 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4011 int nbOfNodes(coo->getNumberOfTuples());
4012 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4013 std::vector<int> neLevs(getNonEmptyLevels());
4014 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4016 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4017 if(zeLev->isMeshStoredSplitByType())
4019 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4020 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4022 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4026 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4027 mesh->computeNodeIdsAlg(nodeIdsInUse);
4030 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4031 if(nbrOfNodesInUse==nbOfNodes)
4032 return 0;//no need to update _part_coords
4033 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4034 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4035 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4036 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4037 MCAuto<DataArrayInt> newFamCoords;
4038 MCAuto<DataArrayAsciiChar> newNameCoords;
4039 if((const DataArrayInt *)_fam_coords)
4040 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4041 MCAuto<DataArrayInt> newNumCoords;
4042 if((const DataArrayInt *)_num_coords)
4043 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4044 if((const DataArrayAsciiChar *)_name_coords)
4045 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4046 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4047 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4049 if((MEDFileUMeshSplitL1*)*it)
4051 (*it)->renumberNodesInConn(ret->begin());
4052 (*it)->setCoords(_coords);
4055 // updates _part_coords
4056 const PartDefinition *pc(_part_coords);
4059 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4060 _part_coords=tmpPD->composeWith(pc);
4066 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4067 * The extraction of \a this is specified by the extractDef \a input map.
4068 * This map tells for each level of cells, the cells kept in the extraction.
4070 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4071 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4073 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4075 std::vector<int> levs(getNonEmptyLevels());
4076 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4077 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4080 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4081 if((*it).second.isNull())
4082 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4085 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4087 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4088 throw INTERP_KERNEL::Exception(oss.str());
4090 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4091 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4092 mPart->computeNodeIdsAlg(fetchedNodes);
4094 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4098 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4100 * \return - a new reference of MEDFileUMesh
4101 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4103 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4105 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4106 std::vector<int> levs(getNonEmptyLevels());
4107 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4110 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4111 if((*it).second.isNull())
4112 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4115 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4117 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4118 throw INTERP_KERNEL::Exception(oss.str());
4120 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4121 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4122 ret->setMeshAtLevel((*it).first,mPart);
4123 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4126 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4127 ret->setFamilyFieldArr((*it).first,famPart);
4131 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4132 ret->setFamilyFieldArr((*it).first,numPart);
4135 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4136 if(it2!=extractDef.end())
4138 const DataArrayDouble *coo(ret->getCoords());
4140 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4141 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4142 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4143 ret->setCoords(cooPart);
4144 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4147 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4148 ret->setFamilyFieldArr(1,famPart);
4152 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4153 ret->setFamilyFieldArr(1,numPart);
4155 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4159 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4160 m->renumberNodesInConn(o2nNodes->begin());
4161 ret->setMeshAtLevel((*it3).first,m);
4168 * This method performs an extrusion along a path defined by \a m1D.
4169 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4170 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4171 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4172 * This method scans all levels in \a this
4173 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4175 * \param [in] m1D - the mesh defining the extrusion path.
4176 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4177 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4179 * \sa MEDCouplingUMesh::buildExtrudedMesh
4181 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4184 if(getMeshDimension()!=2)
4185 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4186 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4187 m1D->checkConsistencyLight();
4188 if(m1D->getMeshDimension()!=1)
4189 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4190 int nbRep(m1D->getNumberOfCells());
4191 std::vector<int> levs(getNonEmptyLevels());
4192 std::vector<std::string> grps(getGroupsNames());
4193 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4194 DataArrayDouble *coords(0);
4195 std::size_t nbOfLevsOut(levs.size()+1);
4196 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4197 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4199 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4200 item=item->clone(false);
4201 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4202 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4203 tmp->changeSpaceDimension(3+(*lev),0.);
4204 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4205 zeList.push_back(elt);
4207 coords=elt->getCoords();
4210 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4211 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4213 (*it)->setName(getName());
4214 (*it)->setCoords(coords);
4216 for(std::size_t ii=0;ii!=zeList.size();ii++)
4219 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4222 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4223 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4224 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4225 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4226 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4227 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4228 std::vector<const MEDCouplingUMesh *> elts(3);
4229 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4230 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4231 elt->setName(getName());
4234 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4235 ret->setMeshAtLevel(lev,elt);
4237 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4238 endLev=endLev->clone(false); endLev->setCoords(coords);
4239 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4240 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4241 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4242 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4243 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4244 endLev->setName(getName());
4245 ret->setMeshAtLevel(levs.back()-1,endLev);
4247 for(std::size_t ii=0;ii!=zeList.size();ii++)
4250 std::vector< MCAuto<DataArrayInt> > outGrps;
4251 std::vector< const DataArrayInt * > outGrps2;
4254 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4256 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4257 if(!grpArr->empty())
4259 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4260 int offset0(zeList[ii]->getNumberOfCells());
4261 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4262 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4263 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4264 grpArr2->setName(oss.str());
4265 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4266 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4267 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4268 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4273 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4275 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4276 if(!grpArr->empty())
4278 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4279 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4280 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4281 for(int iii=0;iii<nbRep;iii++)
4283 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4284 grpArrs2[iii]=grpArrs[iii];
4286 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4287 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4288 std::ostringstream grpName; grpName << *grp << "_extruded";
4289 grpArrExt->setName(grpName.str());
4290 outGrps.push_back(grpArrExt);
4291 outGrps2.push_back(grpArrExt);
4294 ret->setGroupsAtLevel(lev,outGrps2);
4296 std::vector< MCAuto<DataArrayInt> > outGrps;
4297 std::vector< const DataArrayInt * > outGrps2;
4298 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4300 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4301 if(grpArr1->empty())
4303 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4304 std::ostringstream grpName; grpName << *grp << "_top";
4305 grpArr2->setName(grpName.str());
4306 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4307 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4308 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4310 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4315 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4316 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4317 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4319 * \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
4320 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4321 * \param [in] eps - detection threshold for coordinates.
4322 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4324 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4326 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4329 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4330 int initialNbNodes(getNumberOfNodes());
4331 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4332 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4334 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4336 DataArrayDouble *zeCoords(m0->getCoords());
4337 ret->setMeshAtLevel(0,m0);
4338 std::vector<int> levs(getNonEmptyLevels());
4339 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4342 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4343 ret->setFamilyFieldArr(0,famFieldCpy);
4345 famField=getFamilyFieldAtLevel(1);
4348 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4349 fam->fillWithZero();
4350 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4351 ret->setFamilyFieldArr(1,fam);
4353 ret->copyFamGrpMapsFrom(*this);
4354 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4355 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4359 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4360 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4361 if(m1->getMeshDimension()!=0)
4364 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4365 }//kill unused notUsed var
4366 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4368 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4369 MCAuto<DataArrayInt> bSafe(b);
4372 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4373 throw INTERP_KERNEL::Exception(oss.str().c_str());
4375 b->applyLin(1,initialNbNodes);
4376 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4377 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4378 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4379 m1->renumberNodesInConn(renum->begin());
4381 m1->setCoords(zeCoords);
4382 ret->setMeshAtLevel(*lev,m1);
4383 famField=getFamilyFieldAtLevel(*lev);
4386 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4387 ret->setFamilyFieldArr(*lev,famFieldCpy);
4394 * This method converts all quadratic cells in \a this into linear cells.
4395 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4396 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4398 * \param [in] eps - detection threshold for coordinates.
4399 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4401 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4403 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4406 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4407 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4408 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4409 m0->convertQuadraticCellsToLinear();
4411 DataArrayDouble *zeCoords(m0->getCoords());
4412 ret->setMeshAtLevel(0,m0);
4413 std::vector<int> levs(getNonEmptyLevels());
4414 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4417 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4418 ret->setFamilyFieldArr(0,famFieldCpy);
4420 famField=getFamilyFieldAtLevel(1);
4423 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4424 ret->setFamilyFieldArr(1,fam);
4426 ret->copyFamGrpMapsFrom(*this);
4427 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4431 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4432 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4433 m1->convertQuadraticCellsToLinear();
4436 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4437 MCAuto<DataArrayInt> bSafe(b);
4440 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4441 throw INTERP_KERNEL::Exception(oss.str().c_str());
4443 m1->renumberNodesInConn(b->begin());
4444 m1->setCoords(zeCoords);
4445 ret->setMeshAtLevel(*lev,m1);
4446 famField=getFamilyFieldAtLevel(*lev);
4449 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4450 ret->setFamilyFieldArr(*lev,famFieldCpy);
4456 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4458 clearNonDiscrAttributes();
4459 forceComputationOfParts();
4460 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4461 std::vector<int> layer0;
4462 layer0.push_back(getAxisType());//0 i
4463 layer0.push_back(_order); //1 i
4464 layer0.push_back(_iteration);//2 i
4465 layer0.push_back(getSpaceDimension());//3 i
4466 tinyDouble.push_back(_time);//0 d
4467 tinyStr.push_back(_name);//0 s
4468 tinyStr.push_back(_desc_name);//1 s
4469 for(int i=0;i<getSpaceDimension();i++)
4470 tinyStr.push_back(_coords->getInfoOnComponent(i));
4471 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4472 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4474 tinyStr.push_back((*it).first);
4475 layer0.push_back((*it).second);
4477 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4478 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4480 layer0.push_back((int)(*it0).second.size());
4481 tinyStr.push_back((*it0).first);
4482 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4483 tinyStr.push_back(*it1);
4485 // sizeof(layer0)==4+aa+1+bb layer#0
4486 bigArrayD=_coords;// 0 bd
4487 bigArraysI.push_back(_fam_coords);// 0 bi
4488 bigArraysI.push_back(_num_coords);// 1 bi
4489 const PartDefinition *pd(_part_coords);
4491 layer0.push_back(-1);
4494 std::vector<int> tmp0;
4495 pd->serialize(tmp0,bigArraysI);
4496 tinyInt.push_back(tmp0.size());
4497 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4500 std::vector<int> layer1;
4501 std::vector<int> levs(getNonEmptyLevels());
4502 layer1.push_back((int)levs.size());// 0 i <- key
4503 layer1.insert(layer1.end(),levs.begin(),levs.end());
4504 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4506 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4507 lev->serialize(layer1,bigArraysI);
4509 // put layers all together.
4510 tinyInt.push_back(layer0.size());
4511 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4512 tinyInt.push_back(layer1.size());
4513 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4516 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4517 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4519 int sz0(tinyInt[0]);
4520 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4521 int sz1(tinyInt[sz0+1]);
4522 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4524 std::reverse(layer0.begin(),layer0.end());
4525 std::reverse(layer1.begin(),layer1.end());
4526 std::reverse(tinyDouble.begin(),tinyDouble.end());
4527 std::reverse(tinyStr.begin(),tinyStr.end());
4528 std::reverse(bigArraysI.begin(),bigArraysI.end());
4530 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4531 _order=layer0.back(); layer0.pop_back();
4532 _iteration=layer0.back(); layer0.pop_back();
4533 int spaceDim(layer0.back()); layer0.pop_back();
4534 _time=tinyDouble.back(); tinyDouble.pop_back();
4535 _name=tinyStr.back(); tinyStr.pop_back();
4536 _desc_name=tinyStr.back(); tinyStr.pop_back();
4537 _coords=bigArrayD; _coords->rearrange(spaceDim);
4538 for(int i=0;i<spaceDim;i++)
4540 _coords->setInfoOnComponent(i,tinyStr.back());
4543 int nbOfFams(layer0.back()); layer0.pop_back();
4545 for(int i=0;i<nbOfFams;i++)
4547 _families[tinyStr.back()]=layer0.back();
4548 tinyStr.pop_back(); layer0.pop_back();
4550 int nbGroups(layer0.back()); layer0.pop_back();
4552 for(int i=0;i<nbGroups;i++)
4554 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4555 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4556 std::vector<std::string> fams(nbOfFamsOnGrp);
4557 for(int j=0;j<nbOfFamsOnGrp;j++)
4559 fams[j]=tinyStr.back(); tinyStr.pop_back();
4561 _groups[grpName]=fams;
4563 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4564 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4566 int isPd(layer0.back()); layer0.pop_back();
4569 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4570 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4571 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4574 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4576 int nbLevs(layer1.back()); layer1.pop_back();
4577 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4579 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4580 _ms.resize(maxLev+1);
4581 for(int i=0;i<nbLevs;i++)
4585 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4590 * Adds a group of nodes to \a this mesh.
4591 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4592 * The ids should be sorted and different each other (MED file norm).
4594 * \warning this method can alter default "FAMILLE_ZERO" family.
4595 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4597 * \throw If the node coordinates array is not set.
4598 * \throw If \a ids == \c NULL.
4599 * \throw If \a ids->getName() == "".
4600 * \throw If \a ids does not respect the MED file norm.
4601 * \throw If a group with name \a ids->getName() already exists.
4603 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4605 const DataArrayDouble *coords(_coords);
4607 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4608 int nbOfNodes(coords->getNumberOfTuples());
4609 if(!((DataArrayInt *)_fam_coords))
4610 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4612 addGroupUnderground(true,ids,_fam_coords);
4616 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4618 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4619 * The ids should be sorted and different each other (MED file norm).
4621 * \warning this method can alter default "FAMILLE_ZERO" family.
4622 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4624 * \throw If the node coordinates array is not set.
4625 * \throw If \a ids == \c NULL.
4626 * \throw If \a ids->getName() == "".
4627 * \throw If \a ids does not respect the MED file norm.
4628 * \throw If a group with name \a ids->getName() already exists.
4630 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4632 std::vector<int> levs(getNonEmptyLevelsExt());
4633 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4635 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4636 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4638 if(meshDimRelToMaxExt==1)
4639 { addNodeGroup(ids); return ; }
4640 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4641 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4642 addGroupUnderground(false,ids,fam);
4646 * Changes a name of a family specified by its id.
4647 * \param [in] id - the id of the family of interest.
4648 * \param [in] newFamName - the new family name.
4649 * \throw If no family with the given \a id exists.
4651 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4653 std::string oldName=getFamilyNameGivenId(id);
4654 _families.erase(oldName);
4655 _families[newFamName]=id;
4659 * Removes a mesh of a given dimension.
4660 * \param [in] meshDimRelToMax - the relative dimension of interest.
4661 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4663 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4665 std::vector<int> levSet=getNonEmptyLevels();
4666 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4667 if(it==levSet.end())
4668 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4669 int pos=(-meshDimRelToMax);
4674 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4675 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4676 * \param [in] m - the new mesh to set.
4677 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4679 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4680 * another node coordinates array.
4681 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4682 * to the existing meshes of other levels of \a this mesh.
4684 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4686 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4687 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4691 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4692 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4693 * \param [in] m - the new mesh to set.
4694 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4695 * writing \a this mesh in a MED file.
4696 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4698 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4699 * another node coordinates array.
4700 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4701 * to the existing meshes of other levels of \a this mesh.
4703 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4705 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4706 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4709 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4711 dealWithTinyInfo(m);
4712 std::vector<int> levSet=getNonEmptyLevels();
4713 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4715 if((DataArrayDouble *)_coords==0)
4717 DataArrayDouble *c=m->getCoords();
4722 if(m->getCoords()!=_coords)
4723 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4724 int sz=(-meshDimRelToMax)+1;
4725 if(sz>=(int)_ms.size())
4727 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4731 return _ms[-meshDimRelToMax];
4735 * This method allows to set at once the content of different levels in \a this.
4736 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4738 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4739 * \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.
4740 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4742 * \throw If \a there is a null pointer in \a ms.
4743 * \sa MEDFileUMesh::setMeshAtLevel
4745 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4749 const MEDCouplingUMesh *mRef=ms[0];
4751 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4752 std::string name(mRef->getName());
4753 const DataArrayDouble *coo(mRef->getCoords());
4756 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4758 const MEDCouplingUMesh *cur(*it);
4760 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4761 if(coo!=cur->getCoords())
4762 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4763 int mdim=cur->getMeshDimension();
4764 zeDim=std::max(zeDim,mdim);
4765 if(s.find(mdim)!=s.end())
4766 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4768 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4770 int mdim=(*it)->getMeshDimension();
4771 setName((*it)->getName());
4772 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4778 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4779 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4780 * The given meshes must share the same node coordinates array.
4781 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4782 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4783 * create in \a this mesh.
4784 * \throw If \a ms is empty.
4785 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4786 * to the existing meshes of other levels of \a this mesh.
4787 * \throw If the meshes in \a ms do not share the same node coordinates array.
4788 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4789 * of the given meshes.
4790 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
4791 * \throw If names of some meshes in \a ms are equal.
4792 * \throw If \a ms includes a mesh with an empty name.
4794 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4797 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4798 int sz=(-meshDimRelToMax)+1;
4799 if(sz>=(int)_ms.size())
4801 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4802 DataArrayDouble *coo=checkMultiMesh(ms);
4803 if((DataArrayDouble *)_coords==0)
4809 if((DataArrayDouble *)_coords!=coo)
4810 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4811 std::vector<DataArrayInt *> corr;
4812 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4813 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
4814 setMeshAtLevel(meshDimRelToMax,m,renum);
4815 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4816 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4820 * Creates groups at a given level in \a this mesh from a sequence of
4821 * meshes each representing a group.
4822 * The given meshes must share the same node coordinates array.
4823 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4824 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4825 * create in \a this mesh.
4826 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4828 * \throw If \a ms is empty.
4829 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4830 * to the existing meshes of other levels of \a this mesh.
4831 * \throw If the meshes in \a ms do not share the same node coordinates array.
4832 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4833 * of the given meshes.
4834 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
4835 * \throw If names of some meshes in \a ms are equal.
4836 * \throw If \a ms includes a mesh with an empty name.
4838 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4841 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4842 int sz=(-meshDimRelToMax)+1;
4843 if(sz>=(int)_ms.size())
4845 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4846 DataArrayDouble *coo=checkMultiMesh(ms);
4847 if((DataArrayDouble *)_coords==0)
4853 if((DataArrayDouble *)_coords!=coo)
4854 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4855 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4856 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
4858 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4860 DataArrayInt *arr=0;
4861 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4865 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4866 throw INTERP_KERNEL::Exception(oss.str().c_str());
4869 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4870 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4873 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4875 const DataArrayDouble *ret=ms[0]->getCoords();
4876 int mdim=ms[0]->getMeshDimension();
4877 for(unsigned int i=1;i<ms.size();i++)
4879 ms[i]->checkConsistencyLight();
4880 if(ms[i]->getCoords()!=ret)
4881 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4882 if(ms[i]->getMeshDimension()!=mdim)
4883 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4885 return const_cast<DataArrayDouble *>(ret);
4889 * Sets the family field of a given relative dimension.
4890 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4891 * the family field is set.
4892 * \param [in] famArr - the array of the family field.
4893 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4894 * \throw If \a famArr has an invalid size.
4896 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4898 if(meshDimRelToMaxExt==1)
4905 DataArrayDouble *coo(_coords);
4907 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4908 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4913 if(meshDimRelToMaxExt>1)
4914 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4915 int traducedRk=-meshDimRelToMaxExt;
4916 if(traducedRk>=(int)_ms.size())
4917 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4918 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4919 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4920 return _ms[traducedRk]->setFamilyArr(famArr);
4924 * Sets the optional numbers of mesh entities of a given dimension.
4925 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4926 * \param [in] renumArr - the array of the numbers.
4927 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4928 * \throw If \a renumArr has an invalid size.
4930 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4932 if(meshDimRelToMaxExt==1)
4940 DataArrayDouble *coo(_coords);
4942 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4943 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4944 renumArr->incrRef();
4945 _num_coords=renumArr;
4949 if(meshDimRelToMaxExt>1)
4950 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4951 int traducedRk=-meshDimRelToMaxExt;
4952 if(traducedRk>=(int)_ms.size())
4953 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4954 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4955 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4956 return _ms[traducedRk]->setRenumArr(renumArr);
4960 * Sets the optional names of mesh entities of a given dimension.
4961 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4962 * \param [in] nameArr - the array of the names.
4963 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4964 * \throw If \a nameArr has an invalid size.
4966 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4968 if(meshDimRelToMaxExt==1)
4975 DataArrayDouble *coo(_coords);
4977 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4978 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4980 _name_coords=nameArr;
4983 if(meshDimRelToMaxExt>1)
4984 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4985 int traducedRk=-meshDimRelToMaxExt;
4986 if(traducedRk>=(int)_ms.size())
4987 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4988 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4989 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4990 return _ms[traducedRk]->setNameArr(nameArr);
4993 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4995 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4996 if((const MEDFileUMeshSplitL1 *)(*it))
4997 (*it)->synchronizeTinyInfo(*this);
5001 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5003 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5005 DataArrayInt *arr=_fam_coords;
5007 arr->changeValue(oldId,newId);
5008 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5010 MEDFileUMeshSplitL1 *sp=(*it);
5013 sp->changeFamilyIdArr(oldId,newId);
5018 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5020 std::list< MCAuto<DataArrayInt> > ret;
5021 const DataArrayInt *da(_fam_coords);
5023 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5024 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5026 const MEDFileUMeshSplitL1 *elt(*it);
5029 da=elt->getFamilyField();
5031 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5037 void MEDFileUMesh::computeRevNum() const
5039 if((const DataArrayInt *)_num_coords)
5042 int maxValue=_num_coords->getMaxValue(pos);
5043 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5047 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5049 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5052 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5054 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5055 ret.push_back((const DataArrayInt *)_fam_nodes);
5056 ret.push_back((const DataArrayInt *)_num_nodes);
5057 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5058 ret.push_back((const DataArrayInt *)_fam_cells);
5059 ret.push_back((const DataArrayInt *)_num_cells);
5060 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5061 ret.push_back((const DataArrayInt *)_fam_faces);
5062 ret.push_back((const DataArrayInt *)_num_faces);
5063 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5064 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5065 ret.push_back((const DataArrayInt *)_rev_num_cells);
5066 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5070 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5072 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5073 if((const DataArrayInt *)_fam_nodes)
5075 int val=_fam_nodes->getMaxValue(tmp);
5076 ret=std::max(ret,std::abs(val));
5078 if((const DataArrayInt *)_fam_cells)
5080 int val=_fam_cells->getMaxValue(tmp);
5081 ret=std::max(ret,std::abs(val));
5083 if((const DataArrayInt *)_fam_faces)
5085 int val=_fam_faces->getMaxValue(tmp);
5086 ret=std::max(ret,std::abs(val));
5091 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5093 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5094 if((const DataArrayInt *)_fam_nodes)
5096 int val=_fam_nodes->getMaxValue(tmp);
5097 ret=std::max(ret,val);
5099 if((const DataArrayInt *)_fam_cells)
5101 int val=_fam_cells->getMaxValue(tmp);
5102 ret=std::max(ret,val);
5104 if((const DataArrayInt *)_fam_faces)
5106 int val=_fam_faces->getMaxValue(tmp);
5107 ret=std::max(ret,val);
5112 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5114 int ret=std::numeric_limits<int>::max(),tmp=-1;
5115 if((const DataArrayInt *)_fam_nodes)
5117 int val=_fam_nodes->getMinValue(tmp);
5118 ret=std::min(ret,val);
5120 if((const DataArrayInt *)_fam_cells)
5122 int val=_fam_cells->getMinValue(tmp);
5123 ret=std::min(ret,val);
5125 if((const DataArrayInt *)_fam_faces)
5127 int val=_fam_faces->getMinValue(tmp);
5128 ret=std::min(ret,val);
5133 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5135 if(!MEDFileMesh::isEqual(other,eps,what))
5137 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5140 what="Mesh types differ ! This is structured and other is NOT !";
5143 const DataArrayInt *famc1=_fam_nodes;
5144 const DataArrayInt *famc2=otherC->_fam_nodes;
5145 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5147 what="Mismatch of families arr on nodes ! One is defined and not other !";
5152 bool ret=famc1->isEqual(*famc2);
5155 what="Families arr on nodes differ !";
5160 famc2=otherC->_fam_cells;
5161 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5163 what="Mismatch of families arr on cells ! One is defined and not other !";
5168 bool ret=famc1->isEqual(*famc2);
5171 what="Families arr on cells differ !";
5176 famc2=otherC->_fam_faces;
5177 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5179 what="Mismatch of families arr on faces ! One is defined and not other !";
5184 bool ret=famc1->isEqual(*famc2);
5187 what="Families arr on faces differ !";
5192 famc2=otherC->_num_nodes;
5193 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5195 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5200 bool ret=famc1->isEqual(*famc2);
5203 what="Numbering arr on nodes differ !";
5208 famc2=otherC->_num_cells;
5209 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5211 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5216 bool ret=famc1->isEqual(*famc2);
5219 what="Numbering arr on cells differ !";
5224 famc2=otherC->_num_faces;
5225 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5227 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5232 bool ret=famc1->isEqual(*famc2);
5235 what="Numbering arr on faces differ !";
5239 const DataArrayAsciiChar *d1=_names_cells;
5240 const DataArrayAsciiChar *d2=otherC->_names_cells;
5241 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5243 what="Mismatch of naming arr on cells ! One is defined and not other !";
5248 bool ret=d1->isEqual(*d2);
5251 what="Naming arr on cells differ !";
5256 d2=otherC->_names_faces;
5257 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5259 what="Mismatch of naming arr on faces ! One is defined and not other !";
5264 bool ret=d1->isEqual(*d2);
5267 what="Naming arr on faces differ !";
5272 d2=otherC->_names_nodes;
5273 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5275 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5280 bool ret=d1->isEqual(*d2);
5283 what="Naming arr on nodes differ !";
5290 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5292 MEDFileMesh::clearNonDiscrAttributes();
5293 const DataArrayInt *tmp=_fam_nodes;
5295 (const_cast<DataArrayInt *>(tmp))->setName("");
5298 (const_cast<DataArrayInt *>(tmp))->setName("");
5301 (const_cast<DataArrayInt *>(tmp))->setName("");
5304 (const_cast<DataArrayInt *>(tmp))->setName("");
5307 (const_cast<DataArrayInt *>(tmp))->setName("");
5310 (const_cast<DataArrayInt *>(tmp))->setName("");
5314 * Returns ids of mesh entities contained in given families of a given dimension.
5315 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5317 * \param [in] fams - the names of the families of interest.
5318 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5319 * returned instead of ids.
5320 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5321 * numbers, if available and required, of mesh entities of the families. The caller
5322 * is to delete this array using decrRef() as it is no more needed.
5323 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5325 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5327 std::vector<int> famIds(getFamiliesIds(fams));
5328 switch(meshDimRelToMaxExt)
5332 if((const DataArrayInt *)_fam_nodes)
5334 MCAuto<DataArrayInt> da;
5336 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5338 da=_fam_nodes->findIdsEqualList(0,0);
5340 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5345 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5350 if((const DataArrayInt *)_fam_cells)
5352 MCAuto<DataArrayInt> da;
5354 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5356 da=_fam_cells->findIdsEqualList(0,0);
5358 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5363 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5368 if((const DataArrayInt *)_fam_faces)
5370 MCAuto<DataArrayInt> da;
5372 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5374 da=_fam_faces->findIdsEqualList(0,0);
5376 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5381 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5385 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5387 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5391 * Sets the family field of a given relative dimension.
5392 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5393 * the family field is set.
5394 * \param [in] famArr - the array of the family field.
5395 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5396 * \throw If \a famArr has an invalid size.
5397 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5399 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5401 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5403 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5404 switch(meshDimRelToMaxExt)
5408 int nbCells(mesh->getNumberOfCells());
5410 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5416 int nbNodes(mesh->getNumberOfNodes());
5418 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5424 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5426 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5431 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5438 * Sets the optional numbers of mesh entities of a given dimension.
5439 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5440 * \param [in] renumArr - the array of the numbers.
5441 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5442 * \throw If \a renumArr has an invalid size.
5443 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5445 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5447 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5449 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5450 switch(meshDimRelToMaxExt)
5454 int nbCells=mesh->getNumberOfCells();
5455 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5456 _num_cells=renumArr;
5461 int nbNodes=mesh->getNumberOfNodes();
5462 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5463 _num_nodes=renumArr;
5468 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5469 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5470 _num_faces=renumArr;
5474 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5477 renumArr->incrRef();
5481 * Sets the optional names of mesh entities of a given dimension.
5482 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5483 * \param [in] nameArr - the array of the names.
5484 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5485 * \throw If \a nameArr has an invalid size.
5487 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5489 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5491 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5492 switch(meshDimRelToMaxExt)
5496 int nbCells=mesh->getNumberOfCells();
5497 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5498 _names_cells=nameArr;
5503 int nbNodes=mesh->getNumberOfNodes();
5504 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5505 _names_nodes=nameArr;
5510 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5511 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5512 _names_cells=nameArr;
5515 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5522 * Adds a group of nodes to \a this mesh.
5523 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5524 * The ids should be sorted and different each other (MED file norm).
5526 * \warning this method can alter default "FAMILLE_ZERO" family.
5527 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5529 * \throw If the node coordinates array is not set.
5530 * \throw If \a ids == \c NULL.
5531 * \throw If \a ids->getName() == "".
5532 * \throw If \a ids does not respect the MED file norm.
5533 * \throw If a group with name \a ids->getName() already exists.
5535 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5541 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5543 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5544 * The ids should be sorted and different each other (MED file norm).
5546 * \warning this method can alter default "FAMILLE_ZERO" family.
5547 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5549 * \throw If the node coordinates array is not set.
5550 * \throw If \a ids == \c NULL.
5551 * \throw If \a ids->getName() == "".
5552 * \throw If \a ids does not respect the MED file norm.
5553 * \throw If a group with name \a ids->getName() already exists.
5555 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5557 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5558 addGroupUnderground(false,ids,fam);
5563 * Returns the family field for mesh entities of a given dimension.
5564 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5565 * \return const DataArrayInt * - the family field. It is an array of ids of families
5566 * each mesh entity belongs to. It can be \c NULL.
5567 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5569 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5571 switch(meshDimRelToMaxExt)
5580 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5585 * Returns the family field for mesh entities of a given dimension.
5586 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5587 * \return const DataArrayInt * - the family field. It is an array of ids of families
5588 * each mesh entity belongs to. It can be \c NULL.
5589 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5591 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5593 switch(meshDimRelToMaxExt)
5602 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5607 * Returns the optional numbers of mesh entities of a given dimension.
5608 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5609 * \return const DataArrayInt * - the array of the entity numbers.
5610 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5611 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5613 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5615 switch(meshDimRelToMaxExt)
5624 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5629 * Returns the optional numbers of mesh entities of a given dimension transformed using
5630 * DataArrayInt::invertArrayN2O2O2N().
5631 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5632 * \return const DataArrayInt * - the array of the entity numbers transformed using
5633 * DataArrayInt::invertArrayN2O2O2N().
5634 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5635 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5637 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5639 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5640 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5641 if(meshDimRelToMaxExt==0)
5643 if((const DataArrayInt *)_num_cells)
5646 int maxValue=_num_cells->getMaxValue(pos);
5647 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5648 return _rev_num_cells;
5651 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5655 if((const DataArrayInt *)_num_nodes)
5658 int maxValue=_num_nodes->getMaxValue(pos);
5659 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5660 return _rev_num_nodes;
5663 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5667 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5669 switch(meshDimRelToMaxExt)
5672 return _names_cells;
5674 return _names_nodes;
5676 return _names_faces;
5678 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5683 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5684 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5686 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5688 std::vector<int> ret(1);
5693 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5694 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5696 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5698 std::vector<int> ret(2);
5704 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5706 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5708 std::vector<int> ret;
5709 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5720 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5722 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5724 std::vector<int> ret;
5725 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5736 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5738 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5740 std::vector<int> ret;
5741 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5752 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5754 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5756 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5760 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5762 DataArrayInt *arr=_fam_nodes;
5764 arr->changeValue(oldId,newId);
5767 arr->changeValue(oldId,newId);
5770 arr->changeValue(oldId,newId);
5773 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5775 std::list< MCAuto<DataArrayInt> > ret;
5776 const DataArrayInt *da(_fam_nodes);
5778 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5781 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5784 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5788 void MEDFileStructuredMesh::deepCpyAttributes()
5790 if((const DataArrayInt*)_fam_nodes)
5791 _fam_nodes=_fam_nodes->deepCopy();
5792 if((const DataArrayInt*)_num_nodes)
5793 _num_nodes=_num_nodes->deepCopy();
5794 if((const DataArrayAsciiChar*)_names_nodes)
5795 _names_nodes=_names_nodes->deepCopy();
5796 if((const DataArrayInt*)_fam_cells)
5797 _fam_cells=_fam_cells->deepCopy();
5798 if((const DataArrayInt*)_num_cells)
5799 _num_cells=_num_cells->deepCopy();
5800 if((const DataArrayAsciiChar*)_names_cells)
5801 _names_cells=_names_cells->deepCopy();
5802 if((const DataArrayInt*)_fam_faces)
5803 _fam_faces=_fam_faces->deepCopy();
5804 if((const DataArrayInt*)_num_faces)
5805 _num_faces=_num_faces->deepCopy();
5806 if((const DataArrayAsciiChar*)_names_faces)
5807 _names_faces=_names_faces->deepCopy();
5808 if((const DataArrayInt*)_rev_num_nodes)
5809 _rev_num_nodes=_rev_num_nodes->deepCopy();
5810 if((const DataArrayInt*)_rev_num_cells)
5811 _rev_num_cells=_rev_num_cells->deepCopy();
5815 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5817 * \return a pointer to cartesian mesh that need to be managed by the caller.
5818 * \warning the returned pointer has to be managed by the caller.
5822 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5823 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5824 * \param [in] renum - it must be \c false.
5825 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5826 * delete using decrRef() as it is no more needed.
5828 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
5832 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5833 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5834 switch(meshDimRelToMax)
5840 return const_cast<MEDCouplingStructuredMesh *>(m);
5845 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5846 buildMinusOneImplicitPartIfNeeded();
5847 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
5853 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5857 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
5859 std::vector<int> ret;
5860 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
5861 if(famCells && famCells->presenceOfValue(ret))
5863 if(famFaces && famFaces->presenceOfValue(ret))
5868 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
5870 std::vector<int> ret(getFamsNonEmptyLevels(fams));
5871 const DataArrayInt *famNodes(_fam_nodes);
5872 if(famNodes && famNodes->presenceOfValue(ret))
5878 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5879 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5880 * \return int - the number of entities.
5881 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5883 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5885 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5887 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5888 switch(meshDimRelToMaxExt)
5891 return cmesh->getNumberOfCells();
5893 return cmesh->getNumberOfNodes();
5895 return cmesh->getNumberOfCellsOfSubLevelMesh();
5897 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5901 int MEDFileStructuredMesh::getNumberOfNodes() const
5903 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5905 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5906 return cmesh->getNumberOfNodes();
5909 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5911 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5913 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5914 switch(meshDimRelToMaxExt)
5917 return cmesh->getNumberOfCells();
5919 return cmesh->getNumberOfCellsOfSubLevelMesh();
5921 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5925 bool MEDFileStructuredMesh::hasImplicitPart() const
5931 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5933 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5935 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5936 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5939 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5940 if(cm.getReverseExtrudedType()!=gt)
5941 throw INTERP_KERNEL::Exception(MSG);
5942 buildImplicitPart();
5943 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5947 if(gt!=zeFaceMesh->getCellModelEnum())
5948 throw INTERP_KERNEL::Exception(MSG);
5949 return zeFaceMesh->getNumberOfCells();
5953 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5955 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5957 buildImplicitPart();
5960 void MEDFileStructuredMesh::buildImplicitPart() const
5962 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5964 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5965 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5968 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5970 _faces_if_necessary=0;
5974 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5975 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5977 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5979 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5982 return _faces_if_necessary;
5985 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5987 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5989 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5990 switch(meshDimRelToMax)
5994 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5999 int mdim(cmesh->getMeshDimension());
6001 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6002 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6006 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6010 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6012 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6015 return getNumberOfCellsAtLevel(0);
6018 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6020 if(st.getNumberOfItems()!=1)
6021 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 !");
6022 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6023 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6024 if(getNumberOfNodes()!=(int)nodesFetched.size())
6025 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6026 if(st[0].getPflName().empty())
6028 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6031 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6032 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6033 int sz(nodesFetched.size());
6034 for(const int *work=arr->begin();work!=arr->end();work++)
6036 std::vector<int> conn;
6037 cmesh->getNodeIdsOfCell(*work,conn);
6038 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6039 if(*it>=0 && *it<sz)
6040 nodesFetched[*it]=true;
6042 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6046 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6048 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6052 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6053 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6055 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6056 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6058 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6061 if(!mrs || mrs->isCellFamilyFieldReading())
6063 famCells=DataArrayInt::New();
6064 famCells->alloc(nbOfElt,1);
6065 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6068 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6071 if(!mrs || mrs->isCellNumFieldReading())
6073 numCells=DataArrayInt::New();
6074 numCells->alloc(nbOfElt,1);
6075 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6078 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6081 if(!mrs || mrs->isCellNameFieldReading())
6083 namesCells=DataArrayAsciiChar::New();
6084 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6085 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6086 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6091 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6093 setName(strm->getName());
6094 setDescription(strm->getDescription());
6095 setUnivName(strm->getUnivName());
6096 setIteration(strm->getIteration());
6097 setOrder(strm->getOrder());
6098 setTimeValue(strm->getTime());
6099 setTimeUnit(strm->getTimeUnit());
6100 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6101 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6102 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6105 if(!mrs || mrs->isNodeFamilyFieldReading())
6107 int nbNodes(getNumberOfNodes());
6109 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6110 _fam_nodes=DataArrayInt::New();
6111 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6112 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...
6113 _fam_nodes->fillWithZero();
6114 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6117 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6120 if(!mrs || mrs->isNodeNumFieldReading())
6122 _num_nodes=DataArrayInt::New();
6123 _num_nodes->alloc(nbOfElt,1);
6124 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6127 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6130 if(!mrs || mrs->isNodeNameFieldReading())
6132 _names_nodes=DataArrayAsciiChar::New();
6133 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6134 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6135 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6138 int meshDim(getStructuredMesh()->getMeshDimension());
6139 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6141 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6144 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6146 int meshDim(getStructuredMesh()->getMeshDimension());
6147 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6149 if((const DataArrayInt *)_fam_cells)
6150 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6151 if((const DataArrayInt *)_fam_faces)
6152 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6153 if((const DataArrayInt *)_fam_nodes)
6154 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6155 if((const DataArrayInt *)_num_cells)
6156 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6157 if((const DataArrayInt *)_num_faces)
6158 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6159 if((const DataArrayInt *)_num_nodes)
6160 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6161 if((const DataArrayAsciiChar *)_names_cells)
6163 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6165 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6166 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6167 throw INTERP_KERNEL::Exception(oss.str().c_str());
6169 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6171 if((const DataArrayAsciiChar *)_names_faces)
6173 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6175 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6176 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6177 throw INTERP_KERNEL::Exception(oss.str().c_str());
6179 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6181 if((const DataArrayAsciiChar *)_names_nodes)
6183 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6185 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6186 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6187 throw INTERP_KERNEL::Exception(oss.str().c_str());
6189 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6192 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6196 * Returns an empty instance of MEDFileCMesh.
6197 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6198 * mesh using decrRef() as it is no more needed.
6200 MEDFileCMesh *MEDFileCMesh::New()
6202 return new MEDFileCMesh;
6206 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6207 * file. The first mesh in the file is loaded.
6208 * \param [in] fileName - the name of MED file to read.
6209 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6210 * mesh using decrRef() as it is no more needed.
6211 * \throw If the file is not readable.
6212 * \throw If there is no meshes in the file.
6213 * \throw If the mesh in the file is not a Cartesian one.
6215 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6217 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6220 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6221 throw INTERP_KERNEL::Exception(oss.str().c_str());
6223 MEDFileUtilities::CheckFileForRead(fileName);
6224 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6226 MEDCoupling::MEDCouplingMeshType meshType;
6228 MEDCoupling::MEDCouplingAxisType dummy3;
6229 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6230 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
6234 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6235 * file. The mesh to load is specified by its name and numbers of a time step and an
6237 * \param [in] fileName - the name of MED file to read.
6238 * \param [in] mName - the name of the mesh to read.
6239 * \param [in] dt - the number of a time step.
6240 * \param [in] it - the number of an iteration.
6241 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6242 * mesh using decrRef() as it is no more needed.
6243 * \throw If the file is not readable.
6244 * \throw If there is no mesh with given attributes in the file.
6245 * \throw If the mesh in the file is not a Cartesian one.
6247 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6249 MEDFileUtilities::CheckFileForRead(fileName);
6250 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6251 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6254 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6256 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6259 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6261 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6262 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6267 * Returns the dimension on cells in \a this mesh.
6268 * \return int - the mesh dimension.
6269 * \throw If there are no cells in this mesh.
6271 int MEDFileCMesh::getMeshDimension() const
6273 if(!((const MEDCouplingCMesh*)_cmesh))
6274 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6275 return _cmesh->getMeshDimension();
6279 * Returns the dimension on nodes in \a this mesh.
6280 * \return int - the space dimension.
6281 * \throw If there are no cells in this mesh.
6283 int MEDFileCMesh::getSpaceDimension() const
6285 if(!((const MEDCouplingCMesh*)_cmesh))
6286 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6287 return _cmesh->getSpaceDimension();
6291 * Returns a string describing \a this mesh.
6292 * \return std::string - the mesh information string.
6294 std::string MEDFileCMesh::simpleRepr() const
6296 return MEDFileStructuredMesh::simpleRepr();
6300 * Returns a full textual description of \a this mesh.
6301 * \return std::string - the string holding the mesh description.
6303 std::string MEDFileCMesh::advancedRepr() const
6305 return simpleRepr();
6308 MEDFileMesh *MEDFileCMesh::shallowCpy() const
6310 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6314 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6316 return new MEDFileCMesh;
6319 MEDFileMesh *MEDFileCMesh::deepCopy() const
6321 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6322 ret->deepCpyEquivalences(*this);
6323 if((const MEDCouplingCMesh*)_cmesh)
6324 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6325 ret->deepCpyAttributes();
6330 * Checks if \a this and another mesh are equal.
6331 * \param [in] other - the mesh to compare with.
6332 * \param [in] eps - a precision used to compare real values.
6333 * \param [in,out] what - the string returning description of unequal data.
6334 * \return bool - \c true if the meshes are equal, \c false, else.
6336 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6338 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6340 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6343 what="Mesh types differ ! This is cartesian and other is NOT !";
6346 clearNonDiscrAttributes();
6347 otherC->clearNonDiscrAttributes();
6348 const MEDCouplingCMesh *coo1=_cmesh;
6349 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6350 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6352 what="Mismatch of cartesian meshes ! One is defined and not other !";
6357 bool ret=coo1->isEqual(coo2,eps);
6360 what="cartesian meshes differ !";
6368 * Clears redundant attributes of incorporated data arrays.
6370 void MEDFileCMesh::clearNonDiscrAttributes() const
6372 MEDFileStructuredMesh::clearNonDiscrAttributes();
6373 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6376 MEDFileCMesh::MEDFileCMesh()
6380 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6383 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6385 catch(INTERP_KERNEL::Exception& e)
6390 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6392 MEDCoupling::MEDCouplingMeshType meshType;
6395 MEDCoupling::MEDCouplingAxisType axType;
6396 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6397 if(meshType!=CARTESIAN)
6399 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6400 throw INTERP_KERNEL::Exception(oss.str().c_str());
6402 MEDFileCMeshL2 loaderl2;
6403 loaderl2.loadAll(fid,mid,mName,dt,it);
6404 setAxisType(axType);
6405 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6408 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6412 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6413 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6415 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6417 synchronizeTinyInfoOnLeaves();
6421 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6423 synchronizeTinyInfoOnLeaves();
6428 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6429 * \param [in] m - the new MEDCouplingCMesh to refer to.
6430 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6433 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6435 dealWithTinyInfo(m);
6441 MEDFileMesh *MEDFileCMesh::cartesianize() const
6443 if(getAxisType()==AX_CART)
6446 return const_cast<MEDFileCMesh *>(this);
6450 const MEDCouplingCMesh *cmesh(getMesh());
6452 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6453 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6454 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6455 clmesh->setCoords(coords);
6456 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6457 ret->MEDFileStructuredMesh::operator=(*this);
6458 ret->setMesh(clmesh);
6459 ret->setAxisType(AX_CART);
6464 void MEDFileCMesh::writeLL(med_idt fid) const
6466 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6467 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6468 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6469 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6470 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6471 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6472 int spaceDim(_cmesh->getSpaceDimension());
6473 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6474 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6475 for(int i=0;i<spaceDim;i++)
6477 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6479 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6480 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
6481 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
6483 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6485 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6486 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6487 for(int i=0;i<spaceDim;i++)
6489 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6490 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6493 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6494 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6497 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6499 const MEDCouplingCMesh *cmesh=_cmesh;
6502 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6503 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6504 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6505 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6508 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6510 return new MEDFileCurveLinearMesh;
6513 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6515 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6518 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6519 throw INTERP_KERNEL::Exception(oss.str().c_str());
6521 MEDFileUtilities::CheckFileForRead(fileName);
6522 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6524 MEDCoupling::MEDCouplingMeshType meshType;
6525 MEDCoupling::MEDCouplingAxisType dummy3;
6527 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6528 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6531 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6533 MEDFileUtilities::CheckFileForRead(fileName);
6534 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6535 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6538 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6540 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6543 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6545 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6546 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6550 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6552 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6556 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6558 return new MEDFileCurveLinearMesh;
6561 MEDFileMesh *MEDFileCurveLinearMesh::deepCopy() const
6563 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6564 ret->deepCpyEquivalences(*this);
6565 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6566 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6567 ret->deepCpyAttributes();
6571 int MEDFileCurveLinearMesh::getMeshDimension() const
6573 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6574 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6575 return _clmesh->getMeshDimension();
6578 std::string MEDFileCurveLinearMesh::simpleRepr() const
6580 return MEDFileStructuredMesh::simpleRepr();
6583 std::string MEDFileCurveLinearMesh::advancedRepr() const
6585 return simpleRepr();
6588 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6590 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6592 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6595 what="Mesh types differ ! This is curve linear and other is NOT !";
6598 clearNonDiscrAttributes();
6599 otherC->clearNonDiscrAttributes();
6600 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6601 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6602 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6604 what="Mismatch of curve linear meshes ! One is defined and not other !";
6609 bool ret=coo1->isEqual(coo2,eps);
6612 what="curve linear meshes differ !";
6619 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6621 MEDFileStructuredMesh::clearNonDiscrAttributes();
6622 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6625 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6627 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6630 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6631 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6632 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6633 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6636 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6638 synchronizeTinyInfoOnLeaves();
6642 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6644 dealWithTinyInfo(m);
6650 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6652 if(getAxisType()==AX_CART)
6655 return const_cast<MEDFileCurveLinearMesh *>(this);
6659 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6661 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6662 const DataArrayDouble *coords(mesh->getCoords());
6664 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6665 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6666 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6667 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6668 mesh2->setCoords(coordsCart);
6669 ret->setMesh(mesh2);
6670 ret->setAxisType(AX_CART);
6675 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6677 synchronizeTinyInfoOnLeaves();
6681 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6685 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6688 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6690 catch(INTERP_KERNEL::Exception& e)
6695 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6697 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6698 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6699 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6700 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6701 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6702 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6703 int spaceDim=_clmesh->getSpaceDimension();
6704 int meshDim=_clmesh->getMeshDimension();
6705 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6706 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6707 const DataArrayDouble *coords=_clmesh->getCoords();
6709 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6710 for(int i=0;i<spaceDim;i++)
6712 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6714 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6715 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
6716 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
6718 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6720 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6721 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6722 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6723 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6725 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6727 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6728 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6731 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6733 MEDCoupling::MEDCouplingMeshType meshType;
6736 MEDCoupling::MEDCouplingAxisType axType;
6737 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6738 setAxisType(axType);
6739 if(meshType!=CURVE_LINEAR)
6741 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6742 throw INTERP_KERNEL::Exception(oss.str().c_str());
6744 MEDFileCLMeshL2 loaderl2;
6745 loaderl2.loadAll(fid,mid,mName,dt,it);
6746 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6749 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6752 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6754 return new MEDFileMeshMultiTS;
6757 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6759 return new MEDFileMeshMultiTS(fileName);
6762 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6764 return new MEDFileMeshMultiTS(fileName,mName);
6767 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
6769 MCAuto<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6770 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6772 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6773 if((const MEDFileMesh *)*it)
6774 meshOneTs[i]=(*it)->deepCopy();
6775 ret->_mesh_one_ts=meshOneTs;
6779 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6781 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
6784 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6786 std::vector<const BigMemoryObject *> ret;
6787 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6788 ret.push_back((const MEDFileMesh *)*it);
6792 std::string MEDFileMeshMultiTS::getName() const
6794 if(_mesh_one_ts.empty())
6795 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6796 return _mesh_one_ts[0]->getName();
6799 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6801 std::string oldName(getName());
6802 std::vector< std::pair<std::string,std::string> > v(1);
6803 v[0].first=oldName; v[0].second=newMeshName;
6807 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6810 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6812 MEDFileMesh *cur(*it);
6814 ret=cur->changeNames(modifTab) || ret;
6819 void MEDFileMeshMultiTS::cartesianizeMe()
6821 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6823 MEDFileMesh *cur(*it);
6826 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
6832 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6834 if(_mesh_one_ts.empty())
6835 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6836 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6839 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6842 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6843 _mesh_one_ts.resize(1);
6844 mesh1TimeStep->incrRef();
6845 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
6846 _mesh_one_ts[0]=mesh1TimeStep;
6849 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
6851 if ( MEDFileMesh* m = getOneTimeStep() )
6852 return m->getJoints();
6857 * \brief Set Joints that are common to all time-stamps
6859 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
6861 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6863 (*it)->setJoints( joints );
6867 void MEDFileMeshMultiTS::write(med_idt fid) const
6869 MEDFileJoints *joints(getJoints());
6870 bool jointsWritten(false);
6872 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6874 if ( jointsWritten )
6875 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
6877 jointsWritten = true;
6879 (*it)->copyOptionsFrom(*this);
6883 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
6886 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6888 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6889 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6890 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6891 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6895 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6897 MEDFileJoints* joints = 0;
6898 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
6900 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
6901 joints = getOneTimeStep()->getJoints();
6904 _mesh_one_ts.clear(); //for the moment to be improved
6905 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
6908 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6912 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6915 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6918 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6919 throw INTERP_KERNEL::Exception(oss.str().c_str());
6921 MEDFileUtilities::CheckFileForRead(fileName);
6922 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6924 MEDCoupling::MEDCouplingMeshType meshType;
6926 MEDCoupling::MEDCouplingAxisType dummy3;
6927 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6928 loadFromFile(fileName,ms.front());
6930 catch(INTERP_KERNEL::Exception& e)
6935 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6938 loadFromFile(fileName,mName);
6940 catch(INTERP_KERNEL::Exception& e)
6945 MEDFileMeshes *MEDFileMeshes::New()
6947 return new MEDFileMeshes;
6950 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6952 return new MEDFileMeshes(fileName);
6955 void MEDFileMeshes::write(med_idt fid) const
6957 checkConsistencyLight();
6958 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6960 (*it)->copyOptionsFrom(*this);
6965 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6967 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6968 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6969 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6970 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6971 checkConsistencyLight();
6975 int MEDFileMeshes::getNumberOfMeshes() const
6977 return _meshes.size();
6980 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6982 return new MEDFileMeshesIterator(this);
6985 /** Return a borrowed reference (caller is not responsible) */
6986 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6988 if(i<0 || i>=(int)_meshes.size())
6990 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6991 throw INTERP_KERNEL::Exception(oss.str().c_str());
6993 return _meshes[i]->getOneTimeStep();
6996 /** Return a borrowed reference (caller is not responsible) */
6997 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6999 std::vector<std::string> ms=getMeshesNames();
7000 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7003 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7004 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7005 throw INTERP_KERNEL::Exception(oss.str().c_str());
7007 return getMeshAtPos((int)std::distance(ms.begin(),it));
7010 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7012 std::vector<std::string> ret(_meshes.size());
7014 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7016 const MEDFileMeshMultiTS *f=(*it);
7019 ret[i]=f->getName();
7023 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7024 throw INTERP_KERNEL::Exception(oss.str().c_str());
7030 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7033 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7035 MEDFileMeshMultiTS *cur(*it);
7037 ret=cur->changeNames(modifTab) || ret;
7042 void MEDFileMeshes::cartesianizeMe()
7044 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7046 MEDFileMeshMultiTS *cur(*it);
7048 cur->cartesianizeMe();
7052 void MEDFileMeshes::resize(int newSize)
7054 _meshes.resize(newSize);
7057 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7060 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7061 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7062 elt->setOneTimeStep(mesh);
7063 _meshes.push_back(elt);
7066 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7069 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7070 if(i>=(int)_meshes.size())
7071 _meshes.resize(i+1);
7072 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7073 elt->setOneTimeStep(mesh);
7077 void MEDFileMeshes::destroyMeshAtPos(int i)
7079 if(i<0 || i>=(int)_meshes.size())
7081 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7082 throw INTERP_KERNEL::Exception(oss.str().c_str());
7084 _meshes.erase(_meshes.begin()+i);
7087 void MEDFileMeshes::loadFromFile(const std::string& fileName)
7089 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
7091 _meshes.resize(ms.size());
7092 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7093 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
7096 MEDFileMeshes::MEDFileMeshes()
7100 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
7103 loadFromFile(fileName);
7105 catch(INTERP_KERNEL::Exception& /*e*/)
7109 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7111 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7113 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7114 if((const MEDFileMeshMultiTS *)*it)
7115 meshes[i]=(*it)->deepCopy();
7116 MCAuto<MEDFileMeshes> ret=MEDFileMeshes::New();
7117 ret->_meshes=meshes;
7121 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7123 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7126 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7128 std::vector<const BigMemoryObject *> ret;
7129 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7130 ret.push_back((const MEDFileMeshMultiTS *)*it);
7134 std::string MEDFileMeshes::simpleRepr() const
7136 std::ostringstream oss;
7137 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7138 simpleReprWithoutHeader(oss);
7142 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7144 int nbOfMeshes=getNumberOfMeshes();
7145 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7146 std::vector<std::string> mns=getMeshesNames();
7147 for(int i=0;i<nbOfMeshes;i++)
7148 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7151 void MEDFileMeshes::checkConsistencyLight() const
7153 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7155 std::set<std::string> s;
7156 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7158 const MEDFileMeshMultiTS *elt=(*it);
7161 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7162 throw INTERP_KERNEL::Exception(oss.str().c_str());
7164 std::size_t sz=s.size();
7165 s.insert(std::string((*it)->getName()));
7168 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7169 throw INTERP_KERNEL::Exception(oss.str().c_str());
7174 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7179 _nb_iter=ms->getNumberOfMeshes();
7183 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7187 MEDFileMesh *MEDFileMeshesIterator::nextt()
7189 if(_iter_id<_nb_iter)
7191 MEDFileMeshes *ms(_ms);
7193 return ms->getMeshAtPos(_iter_id++);