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 "MEDFileFieldOverView.hxx"
23 #include "MEDFileField.hxx"
24 #include "MEDLoader.hxx"
25 #include "MEDLoaderNS.hxx"
26 #include "MEDFileSafeCaller.txx"
27 #include "MEDLoaderBase.hxx"
29 #include "MEDCouplingUMesh.hxx"
30 #include "MEDCouplingMappedExtrudedMesh.hxx"
32 #include "InterpKernelAutoPtr.hxx"
37 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
38 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
39 extern med_geometry_type typmai3[34];
41 using namespace MEDCoupling;
43 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
45 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
47 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
51 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
53 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
54 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
56 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
57 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
58 ret+=(*it2).capacity();
60 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
61 ret+=(*it).first.capacity()+sizeof(int);
65 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
67 std::vector<const BigMemoryObject *> ret(1);
68 ret[0]=(const MEDFileEquivalences *)_equiv;
73 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
74 * file. The first mesh in the file is loaded.
75 * \param [in] fileName - the name of MED file to read.
76 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
77 * mesh using decrRef() as it is no more needed.
78 * \throw If the file is not readable.
79 * \throw If there is no meshes in the file.
80 * \throw If the mesh in the file is of a not supported type.
82 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
84 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
88 MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
90 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
93 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
94 throw INTERP_KERNEL::Exception(oss.str().c_str());
96 MEDCoupling::MEDCouplingMeshType meshType;
99 MEDCoupling::MEDCouplingAxisType dummy3;
100 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
101 MCAuto<MEDFileMesh> ret;
106 ret=MEDFileUMesh::New();
111 ret=MEDFileCMesh::New();
116 ret=MEDFileCurveLinearMesh::New();
121 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
122 throw INTERP_KERNEL::Exception(oss.str().c_str());
125 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
130 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
131 * file. The mesh to load is specified by its name and numbers of a time step and an
133 * \param [in] fileName - the name of MED file to read.
134 * \param [in] mName - the name of the mesh to read.
135 * \param [in] dt - the number of a time step.
136 * \param [in] it - the number of an iteration.
137 * \param [in] joints - the sub-domain joints to use instead of those that can be read
138 * from the MED file. Usually this joints are those just read by another iteration
139 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
140 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
141 * mesh using decrRef() as it is no more needed.
142 * \throw If the file is not readable.
143 * \throw If there is no mesh with given attributes in the file.
144 * \throw If the mesh in the file is of a not supported type.
146 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
148 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
149 return New(fid,mName,dt,it,mrs,joints);
152 MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
154 MEDCoupling::MEDCouplingMeshType meshType;
157 MEDCoupling::MEDCouplingAxisType dummy3;
158 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
159 MCAuto<MEDFileMesh> ret;
164 ret=MEDFileUMesh::New();
169 ret=MEDFileCMesh::New();
174 ret=MEDFileCurveLinearMesh::New();
179 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
180 throw INTERP_KERNEL::Exception(oss.str().c_str());
183 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
188 * Writes \a this mesh into an open MED file specified by its descriptor.
189 * \param [in] fid - the MED file descriptor.
190 * \throw If the mesh name is not set.
191 * \throw If the file is open for reading only.
192 * \throw If the writing mode == 1 and the same data is present in an existing file.
194 void MEDFileMesh::writeLL(med_idt fid) const
197 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
199 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
202 const MEDFileEquivalences *eqs(_equiv);
208 * Checks if \a this and another mesh are equal.
209 * \param [in] other - the mesh to compare with.
210 * \param [in] eps - a precision used to compare real values.
211 * \param [in,out] what - the string returning description of unequal data.
212 * \return bool - \c true if the meshes are equal, \c false, else.
214 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
216 if(_order!=other->_order)
218 what="Orders differ !";
221 if(_iteration!=other->_iteration)
223 what="Iterations differ !";
226 if(fabs(_time-other->_time)>eps)
228 what="Time values differ !";
231 if(_dt_unit!=other->_dt_unit)
233 what="Time units differ !";
236 if(_name!=other->_name)
238 what="Names differ !";
241 //univ_name has been ignored -> not a bug because it is a mutable attribute
242 if(_desc_name!=other->_desc_name)
244 what="Description names differ !";
247 if(!areGrpsEqual(other,what))
249 if(!areFamsEqual(other,what))
251 if(!areEquivalencesEqual(other,what))
256 void MEDFileMesh::setName(const std::string& name)
262 * Clears redundant attributes of incorporated data arrays.
264 void MEDFileMesh::clearNonDiscrAttributes() const
269 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
271 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
273 if((*it).first==_name)
283 * Copies data on groups and families from another mesh.
284 * \param [in] other - the mesh to copy the data from.
286 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
288 _groups=other._groups;
289 _families=other._families;
294 * This method clear all the groups in the map.
295 * So this method does not operate at all on arrays.
296 * So this method can lead to orphan families.
298 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
300 void MEDFileMesh::clearGrpMap()
306 * This method clear all the families in the map.
307 * So this method does not operate at all on arrays.
308 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
310 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
312 void MEDFileMesh::clearFamMap()
318 * This method clear all the families and groups in the map.
319 * So this method does not operate at all on arrays.
320 * As all groups and families entry will be removed after
321 * 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.
323 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
325 void MEDFileMesh::clearFamGrpMaps()
332 * Returns names of families constituting a group.
333 * \param [in] name - the name of the group of interest.
334 * \return std::vector<std::string> - a sequence of names of the families.
335 * \throw If the name of a nonexistent group is specified.
337 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
339 std::string oname(name);
340 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
341 if(it==_groups.end())
343 std::vector<std::string> grps=getGroupsNames();
344 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
345 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
346 throw INTERP_KERNEL::Exception(oss.str().c_str());
352 * Returns names of families constituting some groups.
353 * \param [in] grps - a sequence of names of groups of interest.
354 * \return std::vector<std::string> - a sequence of names of the families.
355 * \throw If a name of a nonexistent group is present in \a grps.
357 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
359 std::set<std::string> fams;
360 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
362 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
363 if(it2==_groups.end())
365 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
366 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
367 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
368 throw INTERP_KERNEL::Exception(oss.str().c_str());
370 fams.insert((*it2).second.begin(),(*it2).second.end());
372 std::vector<std::string> fams2(fams.begin(),fams.end());
377 * Returns ids of families constituting a group.
378 * \param [in] name - the name of the group of interest.
379 * \return std::vector<int> - sequence of ids of the families.
380 * \throw If the name of a nonexistent group is specified.
382 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
384 std::string oname(name);
385 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
386 std::vector<std::string> grps=getGroupsNames();
387 if(it==_groups.end())
389 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
390 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
391 throw INTERP_KERNEL::Exception(oss.str().c_str());
393 return getFamiliesIds((*it).second);
397 * Sets names of families constituting a group. If data on families of this group is
398 * already present, it is overwritten. Every family in \a fams is checked, and if a
399 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
400 * \param [in] name - the name of the group of interest.
401 * \param [in] fams - a sequence of names of families constituting the group.
403 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
405 std::string oname(name);
407 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
409 std::map<std::string,int>::iterator it2=_families.find(*it1);
410 if(it2==_families.end())
416 * Sets families constituting a group. The families are specified by their ids.
417 * If a family name is not found by its id, an exception is thrown.
418 * If several families have same id, the first one in lexical order is taken.
419 * \param [in] name - the name of the group of interest.
420 * \param [in] famIds - a sequence of ids of families constituting the group.
421 * \throw If a family name is not found by its id.
423 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
425 std::string oname(name);
426 std::vector<std::string> fams(famIds.size());
428 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
430 std::string name2=getFamilyNameGivenId(*it1);
437 * Returns names of groups including a given family.
438 * \param [in] name - the name of the family of interest.
439 * \return std::vector<std::string> - a sequence of names of groups including the family.
441 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
443 std::vector<std::string> ret;
444 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
446 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
449 ret.push_back((*it1).first);
457 * Adds an existing family to groups.
458 * \param [in] famName - a name of family to add to \a grps.
459 * \param [in] grps - a sequence of group names to add the family in.
460 * \throw If a family named \a famName not yet exists.
462 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
464 std::string fName(famName);
465 const std::map<std::string,int>::const_iterator it=_families.find(fName);
466 if(it==_families.end())
468 std::vector<std::string> fams=getFamiliesNames();
469 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
470 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
471 throw INTERP_KERNEL::Exception(oss.str().c_str());
473 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
475 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
476 if(it2!=_groups.end())
477 (*it2).second.push_back(fName);
480 std::vector<std::string> grps2(1,fName);
487 * Returns names of all groups of \a this mesh.
488 * \return std::vector<std::string> - a sequence of group names.
490 std::vector<std::string> MEDFileMesh::getGroupsNames() const
492 std::vector<std::string> ret(_groups.size());
494 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
500 * Returns names of all families of \a this mesh.
501 * \return std::vector<std::string> - a sequence of family names.
503 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
505 std::vector<std::string> ret(_families.size());
507 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
513 * Returns names of all families of \a this mesh but like they would be in file.
514 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
515 * 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 !
516 * For your information internaly in memory such families are renamed to have a nicer API.
518 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
520 std::vector<std::string> ret(getFamiliesNames());
521 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
526 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
527 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
528 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
531 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
533 std::vector<std::string> ret;
534 std::vector<std::string> allGrps(getGroupsNames());
535 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
537 std::vector<int> levs(getGrpNonEmptyLevelsExt((*it)));
538 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
545 * Returns all relative mesh levels (including nodes) where a given group is defined.
546 * \param [in] grp - the name of the group of interest.
547 * \return std::vector<int> - a sequence of the relative dimensions.
549 std::vector<int> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
551 std::vector<std::string> fams(getFamiliesOnGroup(grp));
552 return getFamsNonEmptyLevelsExt(fams);
556 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
557 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
558 * \param [in] grps - a sequence of names of the groups of interest.
559 * \return std::vector<int> - a sequence of the relative dimensions.
561 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
563 std::vector<std::string> fams(getFamiliesOnGroups(grps));
564 return getFamsNonEmptyLevels(fams);
568 * Returns all relative mesh levels (including nodes) where given groups are defined.
569 * \param [in] grps - a sequence of names of the groups of interest.
570 * \return std::vector<int> - a sequence of the relative dimensions.
572 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
574 std::vector<std::string> fams(getFamiliesOnGroups(grps));
575 return getFamsNonEmptyLevelsExt(fams);
579 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
580 * To include nodes, call getGrpNonEmptyLevelsExt() method.
581 * \param [in] grp - the name of the group of interest.
582 * \return std::vector<int> - a sequence of the relative dimensions.
584 std::vector<int> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
586 std::vector<std::string> fams(getFamiliesOnGroup(grp));
587 return getFamsNonEmptyLevels(fams);
591 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
592 * To include nodes, call getFamNonEmptyLevelsExt() method.
593 * \param [in] fam - the name of the family of interest.
594 * \return std::vector<int> - a sequence of the relative dimensions.
596 std::vector<int> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
598 std::vector<std::string> fams(1,std::string(fam));
599 return getFamsNonEmptyLevels(fams);
603 * Returns all relative mesh levels (including nodes) where a given family is defined.
604 * \param [in] fam - the name of the family of interest.
605 * \return std::vector<int> - a sequence of the relative dimensions.
607 std::vector<int> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
609 std::vector<std::string> fams(1,std::string(fam));
610 return getFamsNonEmptyLevelsExt(fams);
613 std::string MEDFileMesh::GetMagicFamilyStr()
615 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
619 * Changes a name of every family, included in one group only, to be same as the group name.
620 * \throw If there are families with equal names in \a this mesh.
622 void MEDFileMesh::assignFamilyNameWithGroupName()
624 std::map<std::string, std::vector<std::string> > groups(_groups);
625 std::map<std::string,int> newFams;
626 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
628 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
629 if(grps.size()==1 && groups[grps[0]].size()==1)
631 if(newFams.find(grps[0])!=newFams.end())
633 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
634 throw INTERP_KERNEL::Exception(oss.str().c_str());
636 newFams[grps[0]]=(*it).second;
637 std::vector<std::string>& grps2=groups[grps[0]];
638 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
643 if(newFams.find((*it).first)!=newFams.end())
645 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
646 throw INTERP_KERNEL::Exception(oss.str().c_str());
648 newFams[(*it).first]=(*it).second;
656 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
658 * \return the removed groups.
660 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
662 std::vector<std::string> ret;
663 std::map<std::string, std::vector<std::string> > newGrps;
664 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
666 if((*it).second.empty())
667 ret.push_back((*it).first);
669 newGrps[(*it).first]=(*it).second;
677 * Removes a group from \a this mesh.
678 * \param [in] name - the name of the group to remove.
679 * \throw If no group with such a \a name exists.
681 void MEDFileMesh::removeGroup(const std::string& name)
683 std::string oname(name);
684 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
685 std::vector<std::string> grps=getGroupsNames();
686 if(it==_groups.end())
688 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
689 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
690 throw INTERP_KERNEL::Exception(oss.str().c_str());
696 * Removes a family from \a this mesh.
697 * \param [in] name - the name of the family to remove.
698 * \throw If no family with such a \a name exists.
700 void MEDFileMesh::removeFamily(const std::string& name)
702 std::string oname(name);
703 std::map<std::string, int >::iterator it=_families.find(oname);
704 std::vector<std::string> fams=getFamiliesNames();
705 if(it==_families.end())
707 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
708 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
709 throw INTERP_KERNEL::Exception(oss.str().c_str());
712 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
714 std::vector<std::string>& v=(*it3).second;
715 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
722 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
723 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
724 * family field whatever its level. This method also suppresses the orphan families.
726 * \return - The list of removed groups names.
728 * \sa MEDFileMesh::removeOrphanFamilies.
730 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
732 removeOrphanFamilies();
733 return removeEmptyGroups();
737 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
738 * 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.
740 * \return - The list of removed families names.
741 * \sa MEDFileMesh::removeOrphanGroups.
743 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
745 MCAuto<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
746 std::vector<std::string> ret;
747 if(!((DataArrayInt*)allFamIdsInUse))
749 ret=getFamiliesNames();
750 _families.clear(); _groups.clear();
753 std::map<std::string,int> famMap;
754 std::map<std::string, std::vector<std::string> > grps(_groups);
755 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
757 if(allFamIdsInUse->presenceOfValue((*it).second))
758 famMap[(*it).first]=(*it).second;
761 ret.push_back((*it).first);
762 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
763 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
765 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
766 std::vector<std::string>& famv=(*it3).second;
767 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
773 { _families=famMap; _groups=grps; }
778 * 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
779 * this family is orphan or not.
781 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
783 void MEDFileMesh::removeFamiliesReferedByNoGroups()
785 std::map<std::string,int> fams;
786 std::set<std::string> sfams;
787 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
788 sfams.insert((*it).first);
789 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
790 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
792 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
793 if(*it!=DFT_FAM_NAME)
794 _families.erase(*it);
798 * 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
799 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
800 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
802 * \sa MEDFileMesh::removeOrphanFamilies
804 void MEDFileMesh::rearrangeFamilies()
806 checkOrphanFamilyZero();
807 removeFamiliesReferedByNoGroups();
809 std::vector<int> levels(getNonEmptyLevelsExt());
810 std::set<int> idsRefed;
811 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
812 idsRefed.insert((*it).second);
813 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
815 const DataArrayInt *fams(0);
818 fams=getFamilyFieldAtLevel(*it);
820 catch(INTERP_KERNEL::Exception& e) { }
823 std::vector<bool> v(fams->getNumberOfTuples(),false);
824 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
825 fams->switchOnTupleEqualTo(*pt,v);
826 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
827 if(!unfetchedIds->empty())
829 MCAuto<DataArrayInt> newFams(fams->deepCopy());
830 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
831 setFamilyFieldArr(*it,newFams);
834 removeOrphanFamilies();
838 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
840 void MEDFileMesh::checkOrphanFamilyZero() const
842 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
844 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
846 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
847 throw INTERP_KERNEL::Exception(oss.str().c_str());
853 * Renames a group in \a this mesh.
854 * \param [in] oldName - a current name of the group to rename.
855 * \param [in] newName - a new group name.
856 * \throw If no group named \a oldName exists in \a this mesh.
857 * \throw If a group named \a newName already exists.
859 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
861 std::string oname(oldName);
862 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
863 std::vector<std::string> grps=getGroupsNames();
864 if(it==_groups.end())
866 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
867 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
868 throw INTERP_KERNEL::Exception(oss.str().c_str());
870 std::string nname(newName);
871 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
872 if(it2!=_groups.end())
874 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
875 throw INTERP_KERNEL::Exception(oss.str().c_str());
877 std::vector<std::string> cpy=(*it).second;
879 _groups[newName]=cpy;
883 * Changes an id of a family in \a this mesh.
884 * This method calls changeFamilyIdArr().
885 * \param [in] oldId - a current id of the family.
886 * \param [in] newId - a new family id.
888 void MEDFileMesh::changeFamilyId(int oldId, int newId)
890 changeFamilyIdArr(oldId,newId);
891 std::map<std::string,int> fam2;
892 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
894 if((*it).second==oldId)
895 fam2[(*it).first]=newId;
897 fam2[(*it).first]=(*it).second;
903 * Renames a family in \a this mesh.
904 * \param [in] oldName - a current name of the family to rename.
905 * \param [in] newName - a new family name.
906 * \throw If no family named \a oldName exists in \a this mesh.
907 * \throw If a family named \a newName already exists.
909 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
911 std::string oname(oldName);
912 std::map<std::string, int >::iterator it=_families.find(oname);
913 std::vector<std::string> fams=getFamiliesNames();
914 if(it==_families.end())
916 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
917 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
918 throw INTERP_KERNEL::Exception(oss.str().c_str());
920 std::string nname(newName);
921 std::map<std::string, int >::iterator it2=_families.find(nname);
922 if(it2!=_families.end())
924 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
925 throw INTERP_KERNEL::Exception(oss.str().c_str());
927 int cpy=(*it).second;
929 _families[newName]=cpy;
930 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
932 std::vector<std::string>& v=(*it3).second;
933 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
940 * Checks if \a this and another mesh contains the same families.
941 * \param [in] other - the mesh to compare with \a this one.
942 * \param [in,out] what - an unused parameter.
943 * \return bool - \c true if number of families and their ids are the same in the two
944 * meshes. Families with the id == \c 0 are not considered.
946 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
948 if(_families==other->_families)
950 std::map<std::string,int> fam0;
951 std::map<std::string,int> fam1;
952 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
954 fam0[(*it).first]=(*it).second;
955 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
957 fam1[(*it).first]=(*it).second;
962 * Checks if \a this and another mesh contains the same groups.
963 * \param [in] other - the mesh to compare with \a this one.
964 * \param [in,out] what - a string describing a difference of groups of the two meshes
965 * in case if this method returns \c false.
966 * \return bool - \c true if number of groups and families constituting them are the
967 * same in the two meshes.
969 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
971 if(_groups==other->_groups)
974 std::size_t sz=_groups.size();
975 if(sz!=other->_groups.size())
977 what="Groups differ because not same number !\n";
982 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
983 for(std::size_t i=0;i<sz && ret;i++,it1++)
985 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
986 if(it2!=other->_groups.end())
988 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
989 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
995 what="A group in first mesh exists not in other !\n";
1001 std::ostringstream oss; oss << "Groups description differs :\n";
1002 oss << "First group description :\n";
1003 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1005 oss << " Group \"" << (*it).first << "\" on following families :\n";
1006 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1007 oss << " \"" << *it2 << "\n";
1009 oss << "Second group description :\n";
1010 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1012 oss << " Group \"" << (*it).first << "\" on following families :\n";
1013 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1014 oss << " \"" << *it2 << "\n";
1022 * Checks if a group with a given name exists in \a this mesh.
1023 * \param [in] groupName - the group name.
1024 * \return bool - \c true the group \a groupName exists in \a this mesh.
1026 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1028 std::string grpName(groupName);
1029 return _groups.find(grpName)!=_groups.end();
1033 * Checks if a family with a given id exists in \a this mesh.
1034 * \param [in] famId - the family id.
1035 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1037 bool MEDFileMesh::existsFamily(int famId) const
1039 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1040 if((*it2).second==famId)
1046 * Checks if a family with a given name exists in \a this mesh.
1047 * \param [in] familyName - the family name.
1048 * \return bool - \c true the family \a familyName exists in \a this mesh.
1050 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1052 std::string fname(familyName);
1053 return _families.find(fname)!=_families.end();
1057 * Sets an id of a family.
1058 * \param [in] familyName - the family name.
1059 * \param [in] id - a new id of the family.
1061 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1063 std::string fname(familyName);
1064 _families[fname]=id;
1067 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1069 std::string fname(familyName);
1070 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1071 if((*it).second==id)
1073 if((*it).first!=familyName)
1075 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1076 throw INTERP_KERNEL::Exception(oss.str().c_str());
1079 _families[fname]=id;
1083 * Adds a family to \a this mesh.
1084 * \param [in] familyName - a name of the family.
1085 * \param [in] famId - an id of the family.
1086 * \throw If a family with the same name or id already exists in \a this mesh.
1088 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1090 std::string fname(familyName);
1091 std::map<std::string,int>::const_iterator it=_families.find(fname);
1092 if(it==_families.end())
1094 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1095 if((*it2).second==famId)
1097 std::ostringstream oss;
1098 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1099 throw INTERP_KERNEL::Exception(oss.str().c_str());
1101 _families[fname]=famId;
1105 if((*it).second!=famId)
1107 std::ostringstream oss;
1108 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1109 throw INTERP_KERNEL::Exception(oss.str().c_str());
1115 * Creates a group including all mesh entities of given dimension.
1116 * \warning This method does \b not guarantee that the created group includes mesh
1117 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1118 * present in family fields of different dimensions. To assure this, call
1119 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1120 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1122 * \param [in] groupName - a name of the new group.
1123 * \throw If a group named \a groupName already exists.
1124 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1125 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1127 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1129 std::string grpName(groupName);
1130 std::vector<int> levs=getNonEmptyLevelsExt();
1131 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1133 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1134 oss << "Available relative ext levels are : ";
1135 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1136 throw INTERP_KERNEL::Exception(oss.str().c_str());
1138 if(existsGroup(groupName))
1140 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1141 oss << "Already existing groups are : ";
1142 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1143 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1144 throw INTERP_KERNEL::Exception(oss.str().c_str());
1146 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1148 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1149 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1150 std::vector<std::string> familiesOnWholeGroup;
1151 for(const int *it=famIds->begin();it!=famIds->end();it++)
1154 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1156 _groups[grpName]=familiesOnWholeGroup;
1160 * Ensures that given family ids do not present in family fields of dimensions different
1161 * than given ones. If a family id is present in the family fields of dimensions different
1162 * than the given ones, a new family is created and the whole data is updated accordingly.
1163 * \param [in] famIds - a sequence of family ids to check.
1164 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1165 * famIds should exclusively belong.
1166 * \return bool - \c true if no modification is done in \a this mesh by this method.
1168 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1170 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1171 std::vector<int> levs=getNonEmptyLevelsExt();
1172 std::set<int> levs2(levs.begin(),levs.end());
1173 std::vector<int> levsToTest;
1174 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1175 std::set<int> famIds2(famIds.begin(),famIds.end());
1178 if(!_families.empty())
1179 maxFamId=getMaxFamilyId()+1;
1180 std::vector<std::string> allFams=getFamiliesNames();
1181 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1183 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1186 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1187 std::vector<int> tmp;
1188 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1189 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1192 std::string famName=getFamilyNameGivenId(*it2);
1193 std::ostringstream oss; oss << "Family_" << maxFamId;
1194 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1195 addFamilyOnAllGroupsHaving(famName,zeName);
1196 _families[zeName]=maxFamId;
1197 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1206 * Adds a family to a given group in \a this mesh. If the group with a given name does
1207 * not exist, it is created.
1208 * \param [in] grpName - the name of the group to add the family in.
1209 * \param [in] famName - the name of the family to add to the group named \a grpName.
1210 * \throw If \a grpName or \a famName is an empty string.
1211 * \throw If no family named \a famName is present in \a this mesh.
1213 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1215 std::string grpn(grpName);
1216 std::string famn(famName);
1217 if(grpn.empty() || famn.empty())
1218 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1219 std::vector<std::string> fams=getFamiliesNames();
1220 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1222 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1223 oss << "Create this family or choose an existing one ! Existing fams are : ";
1224 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1225 throw INTERP_KERNEL::Exception(oss.str().c_str());
1227 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1228 if(it==_groups.end())
1230 _groups[grpn].push_back(famn);
1234 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1235 if(it2==(*it).second.end())
1236 (*it).second.push_back(famn);
1241 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1242 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1243 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1245 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1247 std::string famNameCpp(famName);
1248 std::string otherCpp(otherFamName);
1249 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1251 std::vector<std::string>& v=(*it).second;
1252 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1254 v.push_back(otherCpp);
1260 * \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).
1261 * \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)
1263 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1266 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1267 std::string grpName(ids->getName());
1269 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1270 ids->checkStrictlyMonotonic(true);
1271 famArr->incrRef(); MCAuto<DataArrayInt> famArrTmp(famArr);
1272 std::vector<std::string> grpsNames=getGroupsNames();
1273 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1275 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1276 throw INTERP_KERNEL::Exception(oss.str().c_str());
1278 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1279 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1280 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1281 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1282 std::vector<int> familyIds;
1283 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1284 int maxVal=getTheMaxAbsFamilyId()+1;
1285 std::map<std::string,int> families(_families);
1286 std::map<std::string, std::vector<std::string> > groups(_groups);
1287 std::vector<std::string> fams;
1288 bool created(false);
1289 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1291 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1292 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1293 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1294 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1297 bool isFamPresent=false;
1298 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1299 isFamPresent=(*itl)->presenceOfValue(*famId);
1301 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1304 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1305 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1306 fams.push_back(locFamName);
1307 if(existsFamily(*famId))
1309 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1310 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1313 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1317 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1318 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1319 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1320 if(existsFamily(*famId))
1322 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1323 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1328 for(std::size_t i=0;i<familyIds.size();i++)
1330 DataArrayInt *da=idsPerfamiliyIds[i];
1331 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1335 _groups[grpName]=fams;
1338 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1340 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1343 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1345 std::string fam(familyNameToChange);
1346 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1348 std::vector<std::string>& fams((*it).second);
1349 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1353 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1359 * Returns a name of the family having a given id or, if no such a family exists, creates
1360 * a new uniquely named family and returns its name.
1361 * \param [in] id - the id of the family whose name is required.
1362 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1363 * \return std::string - the name of the existing or the created family.
1364 * \throw If it is not possible to create a unique family name.
1366 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1368 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1372 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1373 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1374 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1375 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1377 * This method will throws an exception if it is not possible to create a unique family name.
1379 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1381 std::vector<std::string> famAlreadyExisting(families.size());
1383 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1385 if((*it).second!=id)
1387 famAlreadyExisting[ii]=(*it).first;
1396 std::ostringstream oss; oss << "Family_" << id;
1397 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1403 * Sets names and ids of all families in \a this mesh.
1404 * \param [in] info - a map of a family name to a family id.
1406 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1412 * Sets names of all groups and families constituting them in \a this mesh.
1413 * \param [in] info - a map of a group name to a vector of names of families
1414 * constituting the group.
1416 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1422 * Returns an id of the family having a given name.
1423 * \param [in] name - the name of the family of interest.
1424 * \return int - the id of the family of interest.
1425 * \throw If no family with such a \a name exists.
1427 int MEDFileMesh::getFamilyId(const std::string& name) const
1429 std::map<std::string, int>::const_iterator it=_families.find(name);
1430 if(it==_families.end())
1432 std::vector<std::string> fams(getFamiliesNames());
1433 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1434 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1435 throw INTERP_KERNEL::Exception(oss.str().c_str());
1437 return (*it).second;
1441 * Returns ids of the families having given names.
1442 * \param [in] fams - a sequence of the names of families of interest.
1443 * \return std::vector<int> - a sequence of the ids of families of interest.
1444 * \throw If \a fams contains a name of an inexistent family.
1446 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1448 std::vector<int> ret(fams.size());
1450 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1452 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1453 if(it2==_families.end())
1455 std::vector<std::string> fams2=getFamiliesNames();
1456 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1457 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1458 throw INTERP_KERNEL::Exception(oss.str().c_str());
1460 ret[i]=(*it2).second;
1466 * Returns a maximal abs(id) of families in \a this mesh.
1467 * \return int - the maximal norm of family id.
1468 * \throw If there are no families in \a this mesh.
1470 int MEDFileMesh::getMaxAbsFamilyId() const
1472 if(_families.empty())
1473 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1474 int ret=-std::numeric_limits<int>::max();
1475 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1477 ret=std::max(std::abs((*it).second),ret);
1483 * Returns a maximal id of families in \a this mesh.
1484 * \return int - the maximal family id.
1485 * \throw If there are no families in \a this mesh.
1487 int MEDFileMesh::getMaxFamilyId() const
1489 if(_families.empty())
1490 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1491 int ret=-std::numeric_limits<int>::max();
1492 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1494 ret=std::max((*it).second,ret);
1500 * Returns a minimal id of families in \a this mesh.
1501 * \return int - the minimal family id.
1502 * \throw If there are no families in \a this mesh.
1504 int MEDFileMesh::getMinFamilyId() const
1506 if(_families.empty())
1507 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1508 int ret=std::numeric_limits<int>::max();
1509 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1511 ret=std::min((*it).second,ret);
1517 * Returns a maximal id of families in \a this mesh. Not only named families are
1518 * considered but all family fields as well.
1519 * \return int - the maximal family id.
1521 int MEDFileMesh::getTheMaxAbsFamilyId() const
1523 int m1=-std::numeric_limits<int>::max();
1524 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1525 m1=std::max(std::abs((*it).second),m1);
1526 int m2=getMaxAbsFamilyIdInArrays();
1527 return std::max(m1,m2);
1531 * Returns a maximal id of families in \a this mesh. Not only named families are
1532 * considered but all family fields as well.
1533 * \return int - the maximal family id.
1535 int MEDFileMesh::getTheMaxFamilyId() const
1537 int m1=-std::numeric_limits<int>::max();
1538 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1539 m1=std::max((*it).second,m1);
1540 int m2=getMaxFamilyIdInArrays();
1541 return std::max(m1,m2);
1545 * Returns a minimal id of families in \a this mesh. Not only named families are
1546 * considered but all family fields as well.
1547 * \return int - the minimal family id.
1549 int MEDFileMesh::getTheMinFamilyId() const
1551 int m1=std::numeric_limits<int>::max();
1552 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1553 m1=std::min((*it).second,m1);
1554 int m2=getMinFamilyIdInArrays();
1555 return std::min(m1,m2);
1559 * This method only considers the maps. The contain of family array is ignored here.
1561 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1563 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1565 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1567 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1568 v.insert((*it).second);
1569 ret->alloc((int)v.size(),1);
1570 std::copy(v.begin(),v.end(),ret->getPointer());
1575 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1577 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1579 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1581 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1582 MCAuto<DataArrayInt> ret;
1583 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1585 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1586 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1587 if((DataArrayInt *) ret)
1588 ret=dv->buildUnion(ret);
1596 * true is returned if no modification has been needed. false if family
1597 * renumbering has been needed.
1599 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1601 std::vector<int> levs=getNonEmptyLevelsExt();
1602 std::set<int> allFamIds;
1603 int maxId=getMaxFamilyId()+1;
1604 std::map<int,std::vector<int> > famIdsToRenum;
1605 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1607 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1610 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1612 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1614 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1616 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1619 if(famIdsToRenum.empty())
1621 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1622 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1624 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1625 int *famIdsToChange=fam->getPointer();
1626 std::map<int,int> ren;
1627 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1629 if(allIds->presenceOfValue(*it3))
1631 std::string famName=getFamilyNameGivenId(*it3);
1632 std::vector<std::string> grps=getGroupsOnFamily(famName);
1635 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1636 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1637 addFamilyOnGrp((*it4),newFam);
1640 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1641 for(const int *id=ids->begin();id!=ids->end();id++)
1642 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1648 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1649 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1650 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1651 * This method will throw an exception if a same family id is detected in different level.
1652 * \warning This policy is the opposite of those in MED file documentation ...
1654 void MEDFileMesh::normalizeFamIdsTrio()
1656 ensureDifferentFamIdsPerLevel();
1657 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1658 std::vector<int> levs=getNonEmptyLevelsExt();
1659 std::set<int> levsS(levs.begin(),levs.end());
1660 std::set<std::string> famsFetched;
1661 std::map<std::string,int> families;
1662 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1665 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1669 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1670 std::map<int,int> ren;
1671 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1673 int nbOfTuples=fam->getNumberOfTuples();
1674 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1675 for(int *w=start;w!=start+nbOfTuples;w++)
1677 for(const int *it=tmp->begin();it!=tmp->end();it++)
1679 if(allIds->presenceOfValue(*it))
1681 std::string famName=getFamilyNameGivenId(*it);
1682 families[famName]=ren[*it];
1683 famsFetched.insert(famName);
1688 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1691 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1695 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1696 std::map<int,int> ren;
1697 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1699 int nbOfTuples=fam->getNumberOfTuples();
1700 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1701 for(int *w=start;w!=start+nbOfTuples;w++)
1703 for(const int *it=tmp->begin();it!=tmp->end();it++)
1705 if(allIds->presenceOfValue(*it))
1707 std::string famName=getFamilyNameGivenId(*it);
1708 families[famName]=ren[*it];
1709 famsFetched.insert(famName);
1714 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1716 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1719 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1720 fam->fillWithZero();
1721 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1722 if(allIds->presenceOfValue(*it3))
1724 std::string famName=getFamilyNameGivenId(*it3);
1725 families[famName]=0;
1726 famsFetched.insert(famName);
1731 std::vector<std::string> allFams=getFamiliesNames();
1732 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1733 std::set<std::string> unFetchedIds;
1734 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1735 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1736 families[*it4]=_families[*it4];
1741 * This method normalizes fam id with the following policy.
1742 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1743 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1744 * This method will throw an exception if a same family id is detected in different level.
1746 void MEDFileMesh::normalizeFamIdsMEDFile()
1748 ensureDifferentFamIdsPerLevel();
1749 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1750 std::vector<int> levs=getNonEmptyLevelsExt();
1751 std::set<int> levsS(levs.begin(),levs.end());
1752 std::set<std::string> famsFetched;
1753 std::map<std::string,int> families;
1755 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1758 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1761 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1762 std::map<int,int> ren;
1763 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1765 int nbOfTuples=fam->getNumberOfTuples();
1766 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1767 for(int *w=start;w!=start+nbOfTuples;w++)
1769 for(const int *it=tmp->begin();it!=tmp->end();it++)
1771 if(allIds->presenceOfValue(*it))
1773 std::string famName=getFamilyNameGivenId(*it);
1774 families[famName]=ren[*it];
1775 famsFetched.insert(famName);
1781 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1783 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1786 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1787 std::map<int,int> ren;
1788 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1790 int nbOfTuples=fam->getNumberOfTuples();
1791 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1792 for(int *w=start;w!=start+nbOfTuples;w++)
1794 for(const int *it=tmp->begin();it!=tmp->end();it++)
1796 if(allIds->presenceOfValue(*it))
1798 std::string famName=getFamilyNameGivenId(*it);
1799 families[famName]=ren[*it];
1800 famsFetched.insert(famName);
1806 std::vector<std::string> allFams=getFamiliesNames();
1807 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1808 std::set<std::string> unFetchedIds;
1809 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1810 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1811 families[*it4]=_families[*it4];
1816 * Returns a name of the family by its id. If there are several families having the given
1817 * id, the name first in lexical order is returned.
1818 * \param [in] id - the id of the family whose name is required.
1819 * \return std::string - the name of the found family.
1820 * \throw If no family with the given \a id exists.
1822 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1824 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1825 if((*it).second==id)
1827 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1828 throw INTERP_KERNEL::Exception(oss.str().c_str());
1832 * Returns a string describing \a this mesh. This description includes the mesh name and
1833 * the mesh description string.
1834 * \return std::string - the mesh information string.
1836 std::string MEDFileMesh::simpleRepr() const
1838 std::ostringstream oss;
1839 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1840 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1841 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1846 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1847 * an empty one is created.
1849 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1851 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1854 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1855 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1856 arr->fillWithZero();
1857 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1858 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1862 * Returns ids of mesh entities contained in a given group of a given dimension.
1863 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1865 * \param [in] grp - the name of the group of interest.
1866 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1867 * returned instead of ids.
1868 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1869 * numbers, if available and required, of mesh entities of the group. The caller
1870 * is to delete this array using decrRef() as it is no more needed.
1871 * \throw If the name of a nonexistent group is specified.
1872 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1874 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1876 std::vector<std::string> tmp(1);
1878 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1884 * Returns ids of mesh entities contained in given groups of a given dimension.
1885 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1887 * \param [in] grps - the names of the groups of interest.
1888 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1889 * returned instead of ids.
1890 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1891 * numbers, if available and required, of mesh entities of the groups. The caller
1892 * is to delete this array using decrRef() as it is no more needed.
1893 * \throw If the name of a nonexistent group is present in \a grps.
1894 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1896 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1898 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1899 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1903 * Returns ids of mesh entities contained in a given family of a given dimension.
1904 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1906 * \param [in] fam - the name of the family of interest.
1907 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1908 * returned instead of ids.
1909 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1910 * numbers, if available and required, of mesh entities of the family. The caller
1911 * is to delete this array using decrRef() as it is no more needed.
1912 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1914 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1916 std::vector<std::string> tmp(1);
1918 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1924 * Returns ids of nodes contained in a given group.
1925 * \param [in] grp - the name of the group of interest.
1926 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1927 * returned instead of ids.
1928 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1929 * numbers, if available and required, of nodes of the group. The caller
1930 * is to delete this array using decrRef() as it is no more needed.
1931 * \throw If the name of a nonexistent group is specified.
1932 * \throw If the family field is missing for nodes.
1934 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1936 std::vector<std::string> tmp(1);
1938 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1944 * Returns ids of nodes contained in given groups.
1945 * \param [in] grps - the names of the groups of interest.
1946 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1947 * returned instead of ids.
1948 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1949 * numbers, if available and required, of nodes of the groups. The caller
1950 * is to delete this array using decrRef() as it is no more needed.
1951 * \throw If the name of a nonexistent group is present in \a grps.
1952 * \throw If the family field is missing for nodes.
1954 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1956 return getGroupsArr(1,grps,renum);
1960 * Returns ids of nodes contained in a given group.
1961 * \param [in] grp - the name of the group of interest.
1962 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1963 * returned instead of ids.
1964 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1965 * numbers, if available and required, of nodes of the group. The caller
1966 * is to delete this array using decrRef() as it is no more needed.
1967 * \throw If the name of a nonexistent group is specified.
1968 * \throw If the family field is missing for nodes.
1970 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1972 std::vector<std::string> tmp(1);
1974 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1980 * Returns ids of nodes contained in given families.
1981 * \param [in] fams - the names of the families of interest.
1982 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1983 * returned instead of ids.
1984 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1985 * numbers, if available and required, of nodes of the families. The caller
1986 * is to delete this array using decrRef() as it is no more needed.
1987 * \throw If the family field is missing for nodes.
1989 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1991 return getFamiliesArr(1,fams,renum);
1995 * Adds groups of given dimension and creates corresponding families and family fields
1996 * given ids of mesh entities of each group.
1997 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1998 * \param [in] grps - a sequence of arrays of ids each describing a group.
1999 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2001 * \throw If names of some groups in \a grps are equal.
2002 * \throw If \a grps includes a group with an empty name.
2003 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2004 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2006 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2010 std::set<std::string> grpsName;
2011 std::vector<std::string> grpsName2(grps.size());
2014 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2016 grpsName.insert((*it)->getName());
2017 grpsName2[i]=(*it)->getName();
2019 if(grpsName.size()!=grps.size())
2020 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2021 if(grpsName.find(std::string(""))!=grpsName.end())
2022 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2023 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2024 MCAuto<DataArrayInt> fam;
2025 std::vector< std::vector<int> > fidsOfGroups;
2028 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2032 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2033 for(unsigned int ii=0;ii<grps.size();ii++)
2035 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2036 grps2[ii]->setName(grps[ii]->getName());
2038 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2039 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2042 if(!_families.empty())
2043 offset=getMaxAbsFamilyId()+1;
2044 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2045 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2046 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2047 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2051 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2052 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2053 * For the moment, the two last input parameters are not taken into account.
2055 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2057 std::map<int,std::string> famInv;
2058 for(const int *it=famIds->begin();it!=famIds->end();it++)
2060 std::ostringstream oss;
2061 oss << "Family_" << (*it);
2062 _families[oss.str()]=(*it);
2063 famInv[*it]=oss.str();
2066 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2068 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2070 _groups[grpNames[i]].push_back(famInv[*it2]);
2075 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2077 std::vector<int> levs(getNonEmptyLevels());
2078 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2079 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2081 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2082 ret.insert(ret.end(),elts.begin(),elts.end());
2088 * \sa getAllDistributionOfTypes
2090 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2092 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2093 return mLev->getDistributionOfTypes();
2096 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2098 loadLL(fid,mName,dt,it,mrs);
2099 loadJointsFromFile(fid);
2100 loadEquivalences(fid);
2103 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2105 famArr->applyLin(offset>0?1:-1,offset,0);
2106 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2109 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2110 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2115 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2116 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2117 * If this method fails to find such a name it will throw an exception.
2119 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2122 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2125 std::size_t len=nameTry.length();
2126 for(std::size_t ii=1;ii<len;ii++)
2128 std::string tmp=nameTry.substr(ii,len-ii);
2129 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2135 for(std::size_t i=1;i<30;i++)
2137 std::string tmp1(nameTry.at(0),i);
2139 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2145 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2147 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2149 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2152 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2154 std::size_t nbOfChunks=code.size()/3;
2155 if(code.size()%3!=0)
2156 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2158 for(std::size_t i=0;i<nbOfChunks;i++)
2167 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2168 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2169 * If _name is not empty and that 'm' has the same name nothing is done.
2170 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2172 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2175 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2180 std::string name(m->getName());
2185 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2186 oss << name << "' ! Names must match !";
2187 throw INTERP_KERNEL::Exception(oss.str().c_str());
2191 if(_desc_name.empty())
2192 _desc_name=m->getDescription();
2195 std::string name(m->getDescription());
2198 if(_desc_name!=name)
2200 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2201 oss << name << "' ! Names must match !";
2202 throw INTERP_KERNEL::Exception(oss.str().c_str());
2208 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2210 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2211 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2213 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2214 oss << " - Groups lying on this family : ";
2215 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2216 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2217 oss << std::endl << std::endl;
2222 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2223 * file. The mesh to load is specified by its name and numbers of a time step and an
2225 * \param [in] fileName - the name of MED file to read.
2226 * \param [in] mName - the name of the mesh to read.
2227 * \param [in] dt - the number of a time step.
2228 * \param [in] it - the number of an iteration.
2229 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2230 * mesh using decrRef() as it is no more needed.
2231 * \throw If the file is not readable.
2232 * \throw If there is no mesh with given attributes in the file.
2233 * \throw If the mesh in the file is not an unstructured one.
2235 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2237 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2238 return New(fid,mName,dt,it,mrs);
2241 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2243 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2247 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2248 * file. The first mesh in the file is loaded.
2249 * \param [in] fileName - the name of MED file to read.
2250 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2251 * mesh using decrRef() as it is no more needed.
2252 * \throw If the file is not readable.
2253 * \throw If there is no meshes in the file.
2254 * \throw If the mesh in the file is not an unstructured one.
2256 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2258 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2259 return New(fid,mrs);
2263 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2265 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2268 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2269 throw INTERP_KERNEL::Exception(oss.str().c_str());
2272 MEDCoupling::MEDCouplingMeshType meshType;
2274 MEDCoupling::MEDCouplingAxisType dummy3;
2275 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2276 return T::New(fid,ms.front(),dt,it,mrs);
2279 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2281 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2285 * \b WARNING this implementation is dependant from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2286 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2288 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2291 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2292 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2293 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2294 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2296 m2D->setCoords(m3D->getCoords());
2297 ret->setMeshAtLevel(0,m3D);
2298 ret->setMeshAtLevel(-1,m2D);
2299 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2304 * Returns an empty instance of MEDFileUMesh.
2305 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2306 * mesh using decrRef() as it is no more needed.
2308 MEDFileUMesh *MEDFileUMesh::New()
2310 return new MEDFileUMesh;
2314 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2315 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2316 * \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.
2317 * 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
2318 * at most the memory consumtion.
2320 * \param [in] fileName - the name of the file.
2321 * \param [in] mName - the name of the mesh to be read.
2322 * \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.
2323 * \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.
2324 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2325 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2326 * \param [in] mrs - the request for what to be loaded.
2327 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2329 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)
2331 MEDFileUtilities::CheckFileForRead(fileName);
2332 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2333 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2337 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2338 * This method is \b NOT wrapped into python.
2340 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)
2342 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2343 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2347 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2349 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2350 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2354 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2356 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2357 ret.push_back((const DataArrayDouble*)_coords);
2358 ret.push_back((const DataArrayInt *)_fam_coords);
2359 ret.push_back((const DataArrayInt *)_num_coords);
2360 ret.push_back((const DataArrayInt *)_global_num_coords);
2361 ret.push_back((const DataArrayInt *)_rev_num_coords);
2362 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2363 ret.push_back((const PartDefinition *)_part_coords);
2364 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2365 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2366 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2367 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2371 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2373 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2377 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2379 return new MEDFileUMesh;
2382 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2384 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2385 ret->deepCpyEquivalences(*this);
2386 if(_coords.isNotNull())
2387 ret->_coords=_coords->deepCopy();
2388 if(_fam_coords.isNotNull())
2389 ret->_fam_coords=_fam_coords->deepCopy();
2390 if(_num_coords.isNotNull())
2391 ret->_num_coords=_num_coords->deepCopy();
2392 if(_global_num_coords.isNotNull())
2393 ret->_global_num_coords=_global_num_coords->deepCopy();
2394 if(_rev_num_coords.isNotNull())
2395 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2396 if(_name_coords.isNotNull())
2397 ret->_name_coords=_name_coords->deepCopy();
2399 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2401 if((const MEDFileUMeshSplitL1 *)(*it))
2402 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2404 if((const PartDefinition*)_part_coords)
2405 ret->_part_coords=_part_coords->deepCopy();
2410 * Checks if \a this and another mesh are equal.
2411 * \param [in] other - the mesh to compare with.
2412 * \param [in] eps - a precision used to compare real values.
2413 * \param [in,out] what - the string returning description of unequal data.
2414 * \return bool - \c true if the meshes are equal, \c false, else.
2416 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2418 if(!MEDFileMesh::isEqual(other,eps,what))
2420 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2423 what="Mesh types differ ! This is unstructured and other is NOT !";
2426 clearNonDiscrAttributes();
2427 otherC->clearNonDiscrAttributes();
2428 const DataArrayDouble *coo1=_coords;
2429 const DataArrayDouble *coo2=otherC->_coords;
2430 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2432 what="Mismatch of coordinates ! One is defined and not other !";
2437 bool ret=coo1->isEqual(*coo2,eps);
2440 what="Coords differ !";
2445 const DataArrayInt *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2446 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2448 what="Mismatch of families arr on nodes ! One is defined and not other !";
2453 bool ret=famc1->isEqual(*famc2);
2456 what="Families arr on node differ !";
2462 const DataArrayInt *numc1(_num_coords),*numc2(otherC->_num_coords);
2463 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2465 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2470 bool ret=numc1->isEqual(*numc2);
2473 what="Numbering arr on node differ !";
2479 const DataArrayInt *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2480 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2482 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2487 bool ret=gnumc1->isEqual(*gnumc2);
2490 what="Global numbering arr on node differ !";
2496 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2497 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2499 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2504 bool ret=namec1->isEqual(*namec2);
2507 what="Names arr on node differ !";
2512 if(_ms.size()!=otherC->_ms.size())
2514 what="Number of levels differs !";
2517 std::size_t sz=_ms.size();
2518 for(std::size_t i=0;i<sz;i++)
2520 const MEDFileUMeshSplitL1 *s1=_ms[i];
2521 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2522 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2524 what="Mismatch of presence of sub levels !";
2529 bool ret=s1->isEqual(s2,eps,what);
2534 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2537 if((!pd0 && pd1) || (pd0 && !pd1))
2539 what=std::string("node part def is defined only for one among this or other !");
2542 return pd0->isEqual(pd1,what);
2546 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2547 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2548 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2549 * \throw if internal family array is inconsistent
2550 * \sa checkSMESHConsistency()
2552 void MEDFileUMesh::checkConsistency() const
2554 if(!_coords || !_coords->isAllocated())
2557 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2559 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2560 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2561 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2565 int nbCoo = _coords->getNumberOfTuples();
2566 if (_fam_coords.isNotNull())
2567 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2568 if (_num_coords.isNotNull())
2570 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2572 int maxValue=_num_coords->getMaxValue(pos);
2573 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2574 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2576 if (_global_num_coords.isNotNull())
2578 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2580 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2581 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2582 if (_num_coords && !_num_coords->hasUniqueValues())
2583 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2585 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2586 // Now sub part check:
2587 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2588 it != _ms.end(); it++)
2589 (*it)->checkConsistency();
2594 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2595 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2596 * entities as it likes), or non overlapping between all sub-levels.
2597 * \throw if the condition above is not respected
2599 void MEDFileUMesh::checkSMESHConsistency() const
2602 // For all sub-levels, numbering is either always null or with void intersection:
2605 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2606 std::vector< const DataArrayInt * > v;
2607 bool voidOrNot = ((*it)->_num == 0);
2608 for (it++; it != _ms.end(); it++)
2609 if( ((*it)->_num == 0) != voidOrNot )
2610 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2611 else if (!voidOrNot)
2612 v.push_back((*it)->_num);
2615 // don't forget the 1st one:
2616 v.push_back(_ms[0]->_num);
2617 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2618 if (inter->getNumberOfTuples())
2619 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2625 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2626 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2628 void MEDFileUMesh::clearNodeAndCellNumbers()
2630 _num_coords.nullify();
2631 _rev_num_coords.nullify();
2632 _global_num_coords.nullify();
2633 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2635 (*it)->_num.nullify();
2636 (*it)->_rev_num.nullify();
2637 (*it)->_global_num.nullify();
2642 * Clears redundant attributes of incorporated data arrays.
2644 void MEDFileUMesh::clearNonDiscrAttributes() const
2646 MEDFileMesh::clearNonDiscrAttributes();
2647 if(_coords.isNotNull())
2648 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2649 if(_fam_coords.isNotNull())
2650 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2651 if(_num_coords.isNotNull())
2652 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2653 if(_name_coords.isNotNull())
2654 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2655 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2657 if((*it).isNotNull())
2658 (*it)->clearNonDiscrAttributes();
2662 void MEDFileUMesh::setName(const std::string& name)
2664 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2665 if((*it).isNotNull())
2666 (*it)->setName(name);
2667 MEDFileMesh::setName(name);
2670 MEDFileUMesh::MEDFileUMesh()
2674 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2677 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2679 catch(INTERP_KERNEL::Exception& e)
2685 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2686 * See MEDFileUMesh::LoadPartOf for detailed description.
2690 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)
2692 MEDFileUMeshL2 loaderl2;
2693 MEDCoupling::MEDCouplingMeshType meshType;
2696 MEDCoupling::MEDCouplingAxisType dummy3;
2697 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2698 if(meshType!=UNSTRUCTURED)
2700 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2701 throw INTERP_KERNEL::Exception(oss.str().c_str());
2703 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2704 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2708 * \brief Write joints in a file
2710 void MEDFileMesh::writeJoints(med_idt fid) const
2712 if ( _joints.isNotNull() )
2713 _joints->writeLL(fid);
2717 * \brief Load joints in a file or use provided ones
2719 //================================================================================
2721 * \brief Load joints in a file or use provided ones
2722 * \param [in] fid - MED file descriptor
2723 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2724 * Usually this joints are those just read by another iteration
2725 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2727 //================================================================================
2729 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2731 if ( toUseInstedOfReading )
2732 setJoints( toUseInstedOfReading );
2734 _joints = MEDFileJoints::New( fid, _name );
2737 void MEDFileMesh::loadEquivalences(med_idt fid)
2739 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2741 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2744 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2746 const MEDFileEquivalences *equiv(other._equiv);
2748 _equiv=equiv->deepCopy(this);
2751 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2753 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2754 if(!thisEq && !otherEq)
2756 if(thisEq && otherEq)
2757 return thisEq->isEqual(otherEq,what);
2760 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2765 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2767 const MEDFileEquivalences *equiv(_equiv);
2770 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2771 _equiv->getRepr(oss);
2774 void MEDFileMesh::checkCartesian() const
2776 if(getAxisType()!=AX_CART)
2778 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()) << ").";
2779 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2780 oss << " - call setAxisType(AX_CART)" << std::endl;
2781 oss << " - call cartesianize()";
2782 throw INTERP_KERNEL::Exception(oss.str().c_str());
2787 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2789 int MEDFileMesh::getNumberOfJoints() const
2791 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2795 * \brief Return joints with all adjacent mesh domains
2797 MEDFileJoints * MEDFileMesh::getJoints() const
2799 return const_cast<MEDFileJoints*>(& (*_joints));
2802 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2804 if ( joints != _joints )
2813 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2815 * \sa loadPartUMeshFromFile
2817 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2819 MEDFileUMeshL2 loaderl2;
2820 MEDCoupling::MEDCouplingMeshType meshType;
2823 MEDCoupling::MEDCouplingAxisType axType;
2824 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2825 setAxisType(axType);
2826 if(meshType!=UNSTRUCTURED)
2828 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2829 throw INTERP_KERNEL::Exception(oss.str().c_str());
2831 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2832 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2833 // Structure element part...
2836 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2837 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2841 _elt_str.resize(nModels);
2842 for(int i=0;i<nModels;i++)
2843 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2846 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2848 int lev=loaderl2.getNumberOfLevels();
2850 for(int i=0;i<lev;i++)
2852 if(!loaderl2.emptyLev(i))
2853 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2857 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2859 setName(loaderl2.getName());
2860 setDescription(loaderl2.getDescription());
2861 setUnivName(loaderl2.getUnivName());
2862 setIteration(loaderl2.getIteration());
2863 setOrder(loaderl2.getOrder());
2864 setTimeValue(loaderl2.getTime());
2865 setTimeUnit(loaderl2.getTimeUnit());
2866 _coords=loaderl2.getCoords();
2867 if(!mrs || mrs->isNodeFamilyFieldReading())
2868 _fam_coords=loaderl2.getCoordsFamily();
2869 if(!mrs || mrs->isNodeNumFieldReading())
2870 _num_coords=loaderl2.getCoordsNum();
2871 if(!mrs || mrs->isNodeNameFieldReading())
2872 _name_coords=loaderl2.getCoordsName();
2873 if(!mrs || mrs->isGlobalNodeNumFieldReading())
2874 _global_num_coords=loaderl2.getCoordsGlobalNum();
2875 _part_coords=loaderl2.getPartDefOfCoo();
2879 MEDFileUMesh::~MEDFileUMesh()
2883 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2885 const DataArrayDouble *coo=_coords;
2886 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2887 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2888 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2889 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2890 int spaceDim=coo?coo->getNumberOfComponents():0;
2893 mdim=getMeshDimension();
2894 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2895 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2896 for(int i=0;i<spaceDim;i++)
2898 std::string info=coo->getInfoOnComponent(i);
2900 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2901 MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2902 MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2904 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2906 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2907 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2908 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
2909 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2910 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2911 (*it)->write(fid,meshName,mdim);
2912 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2916 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2917 * \return std::vector<int> - a sequence of the relative dimensions.
2919 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2921 std::vector<int> ret;
2923 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2924 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2931 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2932 * \return std::vector<int> - a sequence of the relative dimensions.
2934 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2936 std::vector<int> ret0=getNonEmptyLevels();
2937 if((const DataArrayDouble *) _coords)
2939 std::vector<int> ret(ret0.size()+1);
2941 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2947 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2949 std::vector<int> ret;
2950 const DataArrayInt *famCoo(_fam_coords);
2954 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2956 const MEDFileUMeshSplitL1 *cur(*it);
2958 if(cur->getFamilyField())
2964 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2966 std::vector<int> ret;
2967 if(_num_coords.isNotNull())
2970 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2972 const MEDFileUMeshSplitL1 *cur(*it);
2974 if(cur->getNumberField())
2980 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2982 std::vector<int> ret;
2983 const DataArrayAsciiChar *nameCoo(_name_coords);
2987 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2989 const MEDFileUMeshSplitL1 *cur(*it);
2991 if(cur->getNameField())
2998 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2999 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3000 * \param [in] fams - the name of the family of interest.
3001 * \return std::vector<int> - a sequence of the relative dimensions.
3003 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3005 std::vector<int> ret;
3006 std::vector<int> levs(getNonEmptyLevels());
3007 std::vector<int> famIds(getFamiliesIds(fams));
3008 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3009 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3015 * Returns all relative mesh levels (including nodes) where given families are defined.
3016 * \param [in] fams - the names of the families of interest.
3017 * \return std::vector<int> - a sequence of the relative dimensions.
3019 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3021 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
3022 const DataArrayInt *famCoords(_fam_coords);
3025 std::vector<int> famIds(getFamiliesIds(fams));
3026 if(famCoords->presenceOfValue(famIds))
3028 std::vector<int> ret(ret0.size()+1);
3030 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3037 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3039 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3040 if((const DataArrayInt *)_fam_coords)
3042 int val=_fam_coords->getMaxValue(tmp);
3043 ret=std::max(ret,std::abs(val));
3045 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3047 if((const MEDFileUMeshSplitL1 *)(*it))
3049 const DataArrayInt *da=(*it)->getFamilyField();
3052 int val=da->getMaxValue(tmp);
3053 ret=std::max(ret,std::abs(val));
3060 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3062 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3063 if((const DataArrayInt *)_fam_coords)
3065 int val=_fam_coords->getMaxValue(tmp);
3066 ret=std::max(ret,val);
3068 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3070 if((const MEDFileUMeshSplitL1 *)(*it))
3072 const DataArrayInt *da=(*it)->getFamilyField();
3075 int val=da->getMaxValue(tmp);
3076 ret=std::max(ret,val);
3083 int MEDFileUMesh::getMinFamilyIdInArrays() const
3085 int ret=std::numeric_limits<int>::max(),tmp=-1;
3086 if((const DataArrayInt *)_fam_coords)
3088 int val=_fam_coords->getMinValue(tmp);
3089 ret=std::min(ret,val);
3091 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3093 if((const MEDFileUMeshSplitL1 *)(*it))
3095 const DataArrayInt *da=(*it)->getFamilyField();
3098 int val=da->getMinValue(tmp);
3099 ret=std::min(ret,val);
3107 * Returns the dimension on cells in \a this mesh.
3108 * \return int - the mesh dimension.
3109 * \throw If there are no cells in this mesh.
3111 int MEDFileUMesh::getMeshDimension() const
3114 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3115 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3116 return (*it)->getMeshDimension()+lev;
3117 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3121 * Returns the space dimension of \a this mesh that is equal to number of components in
3122 * the node coordinates array.
3123 * \return int - the space dimension of \a this mesh.
3124 * \throw If the node coordinates array is not available.
3126 int MEDFileUMesh::getSpaceDimension() const
3128 const DataArrayDouble *coo=_coords;
3130 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3131 return coo->getNumberOfComponents();
3135 * Returns a string describing \a this mesh.
3136 * \return std::string - the mesh information string.
3138 std::string MEDFileUMesh::simpleRepr() const
3140 std::ostringstream oss;
3141 oss << MEDFileMesh::simpleRepr();
3142 const DataArrayDouble *coo=_coords;
3143 oss << "- The dimension of the space is ";
3144 static const char MSG1[]= "*** NO COORDS SET ***";
3145 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3147 oss << _coords->getNumberOfComponents() << std::endl;
3149 oss << MSG1 << std::endl;
3150 oss << "- Type of the mesh : UNSTRUCTURED\n";
3151 oss << "- Number of nodes : ";
3153 oss << _coords->getNumberOfTuples() << std::endl;
3155 oss << MSG1 << std::endl;
3156 std::size_t nbOfLev=_ms.size();
3157 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3158 for(std::size_t i=0;i<nbOfLev;i++)
3160 const MEDFileUMeshSplitL1 *lev=_ms[i];
3161 oss << " - Level #" << -((int) i) << " has dimension : ";
3164 oss << lev->getMeshDimension() << std::endl;
3165 lev->simpleRepr(oss);
3168 oss << MSG2 << std::endl;
3170 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3173 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3174 oss << "- Names of coordinates :" << std::endl;
3175 std::vector<std::string> vars=coo->getVarsOnComponent();
3176 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3177 oss << std::endl << "- Units of coordinates : " << std::endl;
3178 std::vector<std::string> units=coo->getUnitsOnComponent();
3179 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3181 oss << std::endl << std::endl;
3183 getEquivalencesRepr(oss);
3188 * Returns a full textual description of \a this mesh.
3189 * \return std::string - the string holding the mesh description.
3191 std::string MEDFileUMesh::advancedRepr() const
3193 return simpleRepr();
3197 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3198 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3199 * \return int - the number of entities.
3200 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3202 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3204 if(meshDimRelToMaxExt==1)
3206 if(!((const DataArrayDouble *)_coords))
3207 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3208 return _coords->getNumberOfTuples();
3210 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3214 * Returns the family field for mesh entities of a given dimension.
3215 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3216 * \return const DataArrayInt * - the family field. It is an array of ids of families
3217 * each mesh entity belongs to. It can be \c NULL.
3219 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3221 if(meshDimRelToMaxExt==1)
3223 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3224 return l1->getFamilyField();
3227 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3229 if(meshDimRelToMaxExt==1)
3231 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3232 return l1->getFamilyField();
3236 * Returns the optional numbers of mesh entities of a given dimension.
3237 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3238 * \return const DataArrayInt * - the array of the entity numbers.
3239 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3241 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3243 if(meshDimRelToMaxExt==1)
3245 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3246 return l1->getNumberField();
3249 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3251 if(meshDimRelToMaxExt==1)
3252 return _name_coords;
3253 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3254 return l1->getNameField();
3257 MCAuto<DataArrayInt> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3259 if(meshDimRelToMaxExt!=1)
3260 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3261 return _global_num_coords;
3265 * 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).
3267 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3268 * \param [in] gt - The input geometric type for which the part definition is requested.
3269 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3271 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3273 if(meshDimRelToMaxExt==1)
3274 return _part_coords;
3275 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3276 return l1->getPartDef(gt);
3279 int MEDFileUMesh::getNumberOfNodes() const
3281 const DataArrayDouble *coo(_coords);
3283 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3284 return coo->getNumberOfTuples();
3287 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3289 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3290 return l1->getNumberOfCells();
3293 bool MEDFileUMesh::hasImplicitPart() const
3298 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3300 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3303 void MEDFileUMesh::releaseImplicitPartIfAny() const
3307 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3309 std::size_t sz(st.getNumberOfItems());
3310 for(std::size_t i=0;i<sz;i++)
3312 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3313 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3314 if(st[i].getPflName().empty())
3315 m->computeNodeIdsAlg(nodesFetched);
3318 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3319 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3320 m2->computeNodeIdsAlg(nodesFetched);
3325 MEDFileMesh *MEDFileUMesh::cartesianize() const
3327 if(getAxisType()==AX_CART)
3330 return const_cast<MEDFileUMesh *>(this);
3334 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3335 const DataArrayDouble *coords(_coords);
3337 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3338 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3339 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3340 if((const MEDFileUMeshSplitL1 *)(*it))
3341 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3342 ret->_coords=coordsCart;
3343 ret->setAxisType(AX_CART);
3348 bool MEDFileUMesh::presenceOfStructureElements() const
3350 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3351 if((*it).isNotNull())
3356 void MEDFileUMesh::killStructureElements()
3362 * Returns the optional numbers of mesh entities of a given dimension transformed using
3363 * DataArrayInt::invertArrayN2O2O2N().
3364 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3365 * \return const DataArrayInt * - the array of the entity numbers transformed using
3366 * DataArrayInt::invertArrayN2O2O2N().
3367 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3369 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3371 if(meshDimRelToMaxExt==1)
3373 if(_num_coords.isNull())
3374 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3375 return _rev_num_coords;
3377 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3378 return l1->getRevNumberField();
3382 * Returns a pointer to the node coordinates array of \a this mesh \b without
3383 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3385 DataArrayDouble *MEDFileUMesh::getCoords() const
3388 MCAuto<DataArrayDouble> tmp(_coords);
3389 if((DataArrayDouble *)tmp)
3397 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3398 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3400 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3401 * \param [in] grp - the name of the group whose mesh entities are included in the
3403 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3404 * according to the optional numbers of entities, if available.
3405 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3406 * delete this mesh using decrRef() as it is no more needed.
3407 * \throw If the name of a nonexistent group is specified.
3408 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3410 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3413 synchronizeTinyInfoOnLeaves();
3414 std::vector<std::string> tmp(1);
3416 return getGroups(meshDimRelToMaxExt,tmp,renum);
3420 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3421 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3423 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3424 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3426 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3427 * according to the optional numbers of entities, if available.
3428 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3429 * delete this mesh using decrRef() as it is no more needed.
3430 * \throw If a name of a nonexistent group is present in \a grps.
3431 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3433 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3436 synchronizeTinyInfoOnLeaves();
3437 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3438 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3439 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3440 zeRet->setName(grps[0]);
3441 return zeRet.retn();
3445 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3446 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3448 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3449 * \param [in] fam - the name of the family whose mesh entities are included in the
3451 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3452 * according to the optional numbers of entities, if available.
3453 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3454 * delete this mesh using decrRef() as it is no more needed.
3455 * \throw If a name of a nonexistent family is present in \a grps.
3456 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3458 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3461 synchronizeTinyInfoOnLeaves();
3462 std::vector<std::string> tmp(1);
3464 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3468 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3469 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3471 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3472 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3474 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3475 * according to the optional numbers of entities, if available.
3476 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3477 * delete this mesh using decrRef() as it is no more needed.
3478 * \throw If a name of a nonexistent family is present in \a fams.
3479 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3481 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3484 synchronizeTinyInfoOnLeaves();
3485 if(meshDimRelToMaxExt==1)
3487 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3488 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3489 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3493 std::vector<int> famIds=getFamiliesIds(fams);
3494 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3495 MCAuto<MEDCouplingUMesh> zeRet;
3497 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3499 zeRet=l1->getFamilyPart(0,0,renum);
3500 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3501 zeRet->setName(fams[0]);
3502 return zeRet.retn();
3506 * Returns ids of mesh entities contained in given families of a given dimension.
3507 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3509 * \param [in] fams - the names of the families of interest.
3510 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3511 * returned instead of ids.
3512 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3513 * numbers, if available and required, of mesh entities of the families. The caller
3514 * is to delete this array using decrRef() as it is no more needed.
3515 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3517 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3519 std::vector<int> famIds=getFamiliesIds(fams);
3520 if(meshDimRelToMaxExt==1)
3522 if((const DataArrayInt *)_fam_coords)
3524 MCAuto<DataArrayInt> da;
3526 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3528 da=_fam_coords->findIdsEqualList(0,0);
3530 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3535 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3537 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3539 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3541 return l1->getFamilyPartArr(0,0,renum);
3545 * Returns a MEDCouplingUMesh of a given relative dimension.
3546 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3547 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3548 * To build a valid MEDCouplingUMesh from the returned one in this case,
3549 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3550 * \param [in] meshDimRelToMax - the relative dimension of interest.
3551 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3552 * optional numbers of mesh entities.
3553 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3554 * delete using decrRef() as it is no more needed.
3555 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3557 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3560 synchronizeTinyInfoOnLeaves();
3561 if(meshDimRelToMaxExt==1)
3565 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3566 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3567 umesh->setCoords(cc);
3568 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3569 umesh->setName(getName());
3573 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3574 return l1->getWholeMesh(renum);
3577 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3579 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3580 return l1->getDistributionOfTypes();
3584 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3585 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3586 * optional numbers of mesh entities.
3587 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3588 * delete using decrRef() as it is no more needed.
3589 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3591 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3593 return getMeshAtLevel(0,renum);
3597 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3598 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3599 * optional numbers of mesh entities.
3600 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3601 * delete using decrRef() as it is no more needed.
3602 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3604 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3606 return getMeshAtLevel(-1,renum);
3610 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3611 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3612 * optional numbers of mesh entities.
3613 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3614 * delete using decrRef() as it is no more needed.
3615 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3617 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3619 return getMeshAtLevel(-2,renum);
3623 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3624 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3625 * optional numbers of mesh entities.
3626 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3627 * delete using decrRef() as it is no more needed.
3628 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3630 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3632 return getMeshAtLevel(-3,renum);
3636 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3637 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3638 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3639 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3641 void MEDFileUMesh::forceComputationOfParts() const
3643 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3645 const MEDFileUMeshSplitL1 *elt(*it);
3647 elt->forceComputationOfParts();
3652 * This method returns a vector of mesh parts containing each exactly one geometric type.
3653 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3654 * This method is only for memory aware users.
3655 * The returned pointers are **NOT** new object pointer. No need to mange them.
3657 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3660 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3661 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3665 * This method returns the part of \a this having the geometric type \a gt.
3666 * If such part is not existing an exception will be thrown.
3667 * The returned pointer is **NOT** new object pointer. No need to mange it.
3669 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3672 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3673 int lev=(int)cm.getDimension()-getMeshDimension();
3674 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3675 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3679 * This method returns for each geo types in \a this number of cells with this geo type.
3680 * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated.
3681 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3683 * \sa getDistributionOfTypes
3685 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3687 std::vector< std::pair<int,int> > ret;
3688 std::vector<int> nel(getNonEmptyLevels());
3689 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3691 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3692 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3694 int nbCells(getNumberOfCellsWithType(*it1));
3695 ret.push_back(std::pair<int,int>(*it1,nbCells));
3698 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3703 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3704 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3706 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3708 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3709 return sp->getGeoTypes();
3712 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3714 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3715 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3716 return sp->getNumberOfCellsWithType(ct);
3720 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3721 * \param [in] gt - the geometric type for which the family field is asked.
3722 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3723 * delete using decrRef() as it is no more needed.
3724 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3726 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3728 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3729 int lev=(int)cm.getDimension()-getMeshDimension();
3730 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3731 return sp->extractFamilyFieldOnGeoType(gt);
3735 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3736 * \param [in] gt - the geometric type for which the number field is asked.
3737 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3738 * delete using decrRef() as it is no more needed.
3739 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3741 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3743 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3744 int lev=(int)cm.getDimension()-getMeshDimension();
3745 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3746 return sp->extractNumberFieldOnGeoType(gt);
3750 * This method returns for specified geometric type \a gt the relative level to \a this.
3751 * If the relative level is empty an exception will be thrown.
3753 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3755 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3756 int ret((int)cm.getDimension()-getMeshDimension());
3757 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3761 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3763 if(meshDimRelToMaxExt==1)
3764 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3765 if(meshDimRelToMaxExt>1)
3766 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3767 int tracucedRk=-meshDimRelToMaxExt;
3768 if(tracucedRk>=(int)_ms.size())
3769 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3770 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3771 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3772 return _ms[tracucedRk];
3775 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3777 if(meshDimRelToMaxExt==1)
3778 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3779 if(meshDimRelToMaxExt>1)
3780 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3781 int tracucedRk=-meshDimRelToMaxExt;
3782 if(tracucedRk>=(int)_ms.size())
3783 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3784 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3785 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3786 return _ms[tracucedRk];
3789 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3791 if(-meshDimRelToMax>=(int)_ms.size())
3792 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3794 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3796 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3798 int ref=(*it)->getMeshDimension();
3799 if(ref+i!=meshDim-meshDimRelToMax)
3800 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3806 * Sets the node coordinates array of \a this mesh.
3807 * \param [in] coords - the new node coordinates array.
3808 * \throw If \a coords == \c NULL.
3810 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3813 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3814 if(coords==(DataArrayDouble *)_coords)
3816 coords->checkAllocated();
3817 int nbOfTuples(coords->getNumberOfTuples());
3818 _coords.takeRef(coords);
3819 _fam_coords=DataArrayInt::New();
3820 _fam_coords->alloc(nbOfTuples,1);
3821 _fam_coords->fillWithZero();
3822 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3823 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3824 if((MEDFileUMeshSplitL1 *)(*it))
3825 (*it)->setCoords(coords);
3829 * Change coords without changing anything concerning families and numbering on nodes.
3831 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3834 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3835 if(coords==(DataArrayDouble *)_coords)
3837 coords->checkAllocated();
3838 int nbOfTuples(coords->getNumberOfTuples());
3839 if(_coords.isNull())
3846 int oldNbTuples(_coords->getNumberOfTuples());
3847 if(oldNbTuples!=nbOfTuples)
3848 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3852 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3853 if((MEDFileUMeshSplitL1 *)(*it))
3854 (*it)->setCoords(coords);
3858 * Removes all groups of a given dimension in \a this mesh.
3859 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3860 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3862 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3864 if(meshDimRelToMaxExt==1)
3866 if((DataArrayInt *)_fam_coords)
3867 _fam_coords->fillWithZero();
3870 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3871 l1->eraseFamilyField();
3876 * Removes all families with ids not present in the family fields of \a this mesh.
3878 void MEDFileUMesh::optimizeFamilies()
3880 std::vector<int> levs=getNonEmptyLevelsExt();
3881 std::set<int> allFamsIds;
3882 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3884 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3885 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3887 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3890 std::set<std::string> famNamesToKill;
3891 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3893 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3894 famNamesToKill.insert((*it).first);
3896 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3897 _families.erase(*it);
3898 std::vector<std::string> grpNamesToKill;
3899 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3901 std::vector<std::string> tmp;
3902 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3904 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3905 tmp.push_back(*it2);
3910 tmp.push_back((*it).first);
3912 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3917 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3918 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3919 * The boundary is built according to the following method:
3920 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3921 * coordinates array is extended).
3922 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3923 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3924 * might not be duplicated at all.
3925 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3926 * other side of the group is no more a neighbor)
3927 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3928 * bordering the newly created boundary use the newly computed nodes.
3929 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3930 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3932 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3933 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3935 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3936 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3937 * \sa clearNodeAndCellNumbers()
3939 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3940 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3942 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3943 typedef MCAuto<DataArrayInt> DAInt;
3945 std::vector<int> levs=getNonEmptyLevels();
3946 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3947 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3948 MUMesh m0=getMeshAtLevel(0);
3949 MUMesh m1=getMeshAtLevel(-1);
3950 int nbNodes=m0->getNumberOfNodes();
3951 MUMesh m11=getGroup(-1,grpNameM1);
3952 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3953 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3954 DAInt nodeIdsToDuplicate(tmp00);
3955 DAInt cellsToModifyConn0(tmp11);
3956 DAInt cellsToModifyConn1(tmp22);
3957 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3958 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3959 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3960 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3961 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3962 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3963 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3964 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3965 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3966 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3967 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3968 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3969 DAInt grpIds=getGroupArr(-1,grpNameM1);
3970 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3971 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3972 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3973 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3974 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3975 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3976 m0->setCoords(tmp0->getCoords());
3977 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3978 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3979 m1->setCoords(m0->getCoords());
3980 _coords=m0->getCoords(); _coords->incrRef();
3981 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3982 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3983 DataArrayInt * duplCells;
3984 m1->areCellsIncludedIn(m11, 0, duplCells);
3985 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3986 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3987 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3988 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3989 DAInt szOfCellGrpOfSameType(tmp00);
3990 DAInt idInMsOfCellGrpOfSameType(tmp11);
3992 newm1->setName(getName());
3993 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3995 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3996 DAInt newFam=DataArrayInt::New();
3997 newFam->alloc(newm1->getNumberOfCells(),1);
3998 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3999 // Positive ID for family of nodes, negative for all the rest.
4001 if (m1->getMeshDimension() == 0)
4002 idd=getMaxFamilyId()+1;
4004 idd=getMinFamilyId()-1;
4005 int globStart=0,start=0,end,globEnd;
4006 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4007 for(int i=0;i<nbOfChunks;i++)
4009 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4010 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4012 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4013 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4014 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4019 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4023 newm1->setCoords(getCoords());
4024 setMeshAtLevel(-1,newm1);
4025 setFamilyFieldArr(-1,newFam);
4026 std::string grpName2(grpNameM1); grpName2+="_dup";
4027 addFamily(grpName2,idd);
4028 addFamilyOnGrp(grpName2,grpName2);
4033 int newNbOfNodes=getCoords()->getNumberOfTuples();
4034 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
4035 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4036 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4040 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4042 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4043 it != _ms.end(); it++)
4046 (*it)->_rev_num = 0;
4048 nodesDuplicated=nodeIdsToDuplicate.retn();
4049 cellsModified=cellsToModifyConn0.retn();
4050 cellsNotModified=cellsToModifyConn1.retn();
4053 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4054 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4057 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4058 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4059 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4061 * \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.
4062 * 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.
4064 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4066 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4067 std::vector<int> levs=getNonEmptyLevels();
4069 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4070 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4073 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4075 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4076 std::vector<int> code1=m->getDistributionOfTypes();
4077 end=PutInThirdComponentOfCodeOffset(code1,start);
4078 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4079 bool hasChanged=m->unPolyze();
4080 DataArrayInt *fake=0;
4081 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4082 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4084 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4087 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4088 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4090 MCAuto<DataArrayInt> famField2,numField2;
4091 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4092 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4093 setMeshAtLevel(*it,m);
4094 std::vector<int> code2=m->getDistributionOfTypes();
4095 end=PutInThirdComponentOfCodeOffset(code2,start);
4096 newCode.insert(newCode.end(),code2.begin(),code2.end());
4098 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4102 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4103 setFamilyFieldArr(*it,newFamField);
4107 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4108 setRenumFieldArr(*it,newNumField);
4113 newCode.insert(newCode.end(),code1.begin(),code1.end());
4119 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4120 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4121 o2nRenumCell=o2nRenumCellRet.retn();
4126 /*! \cond HIDDEN_ITEMS */
4127 struct MEDLoaderAccVisit1
4129 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4130 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4131 int _new_nb_of_nodes;
4136 * 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.
4137 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4138 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4139 * -1 values in returned array means that the corresponding old node is no more used.
4141 * \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
4142 * is modified in \a this.
4143 * \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
4146 DataArrayInt *MEDFileUMesh::zipCoords()
4148 const DataArrayDouble *coo(getCoords());
4150 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4151 int nbOfNodes(coo->getNumberOfTuples());
4152 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4153 std::vector<int> neLevs(getNonEmptyLevels());
4154 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4156 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4157 if(zeLev->isMeshStoredSplitByType())
4159 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4160 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4162 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4166 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4167 mesh->computeNodeIdsAlg(nodeIdsInUse);
4170 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4171 if(nbrOfNodesInUse==nbOfNodes)
4172 return 0;//no need to update _part_coords
4173 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4174 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4175 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4176 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4177 MCAuto<DataArrayInt> newFamCoords;
4178 MCAuto<DataArrayAsciiChar> newNameCoords;
4179 if((const DataArrayInt *)_fam_coords)
4180 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4181 MCAuto<DataArrayInt> newNumCoords,newGlobalNumCoords;
4182 if(_num_coords.isNotNull())
4183 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4184 if(_global_num_coords.isNotNull())
4185 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4186 if(_name_coords.isNotNull())
4187 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4188 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4189 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4191 if((MEDFileUMeshSplitL1*)*it)
4193 (*it)->renumberNodesInConn(ret->begin());
4194 (*it)->setCoords(_coords);
4197 // updates _part_coords
4198 const PartDefinition *pc(_part_coords);
4201 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4202 _part_coords=tmpPD->composeWith(pc);
4208 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4209 * The extraction of \a this is specified by the extractDef \a input map.
4210 * This map tells for each level of cells, the cells kept in the extraction.
4212 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4213 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4215 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4217 std::vector<int> levs(getNonEmptyLevels());
4218 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4219 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4222 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4223 if((*it).second.isNull())
4224 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4227 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4229 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4230 throw INTERP_KERNEL::Exception(oss.str());
4232 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4233 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4234 mPart->computeNodeIdsAlg(fetchedNodes);
4236 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4240 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4242 * \return - a new reference of MEDFileUMesh
4243 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4245 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4247 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4248 std::vector<int> levs(getNonEmptyLevels());
4249 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4252 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4253 if((*it).second.isNull())
4254 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4257 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4259 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4260 throw INTERP_KERNEL::Exception(oss.str());
4262 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4263 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4264 ret->setMeshAtLevel((*it).first,mPart);
4265 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4268 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4269 ret->setFamilyFieldArr((*it).first,famPart);
4273 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4274 ret->setFamilyFieldArr((*it).first,numPart);
4277 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4278 if(it2!=extractDef.end())
4280 const DataArrayDouble *coo(ret->getCoords());
4282 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4283 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4284 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4285 ret->setCoords(cooPart);
4286 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4289 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4290 ret->setFamilyFieldArr(1,famPart);
4294 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4295 ret->setFamilyFieldArr(1,numPart);
4297 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4301 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4302 m->renumberNodesInConn(o2nNodes->begin());
4303 ret->setMeshAtLevel((*it3).first,m);
4310 * This method performs an extrusion along a path defined by \a m1D.
4311 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4312 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4313 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4314 * This method scans all levels in \a this
4315 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4317 * \param [in] m1D - the mesh defining the extrusion path.
4318 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4319 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4321 * \sa MEDCouplingUMesh::buildExtrudedMesh
4323 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4326 if(getMeshDimension()!=2)
4327 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4328 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4329 m1D->checkConsistencyLight();
4330 if(m1D->getMeshDimension()!=1)
4331 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4332 int nbRep(m1D->getNumberOfCells());
4333 std::vector<int> levs(getNonEmptyLevels());
4334 std::vector<std::string> grps(getGroupsNames());
4335 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4336 DataArrayDouble *coords(0);
4337 std::size_t nbOfLevsOut(levs.size()+1);
4338 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4339 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4341 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4342 item=item->clone(false);
4343 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4344 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4345 tmp->changeSpaceDimension(3+(*lev),0.);
4346 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4347 zeList.push_back(elt);
4349 coords=elt->getCoords();
4352 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4353 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4355 (*it)->setName(getName());
4356 (*it)->setCoords(coords);
4358 for(std::size_t ii=0;ii!=zeList.size();ii++)
4361 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4364 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4365 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4366 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4367 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4368 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4369 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4370 std::vector<const MEDCouplingUMesh *> elts(3);
4371 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4372 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4373 elt->setName(getName());
4376 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4377 ret->setMeshAtLevel(lev,elt);
4379 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4380 endLev=endLev->clone(false); endLev->setCoords(coords);
4381 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4382 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4383 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4384 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4385 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4386 endLev->setName(getName());
4387 ret->setMeshAtLevel(levs.back()-1,endLev);
4389 for(std::size_t ii=0;ii!=zeList.size();ii++)
4392 std::vector< MCAuto<DataArrayInt> > outGrps;
4393 std::vector< const DataArrayInt * > outGrps2;
4396 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4398 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4399 if(!grpArr->empty())
4401 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4402 int offset0(zeList[ii]->getNumberOfCells());
4403 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4404 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4405 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4406 grpArr2->setName(oss.str());
4407 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4408 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4409 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4410 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4415 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4417 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4418 if(!grpArr->empty())
4420 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4421 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4422 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4423 for(int iii=0;iii<nbRep;iii++)
4425 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4426 grpArrs2[iii]=grpArrs[iii];
4428 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4429 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4430 std::ostringstream grpName; grpName << *grp << "_extruded";
4431 grpArrExt->setName(grpName.str());
4432 outGrps.push_back(grpArrExt);
4433 outGrps2.push_back(grpArrExt);
4436 ret->setGroupsAtLevel(lev,outGrps2);
4438 std::vector< MCAuto<DataArrayInt> > outGrps;
4439 std::vector< const DataArrayInt * > outGrps2;
4440 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4442 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4443 if(grpArr1->empty())
4445 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4446 std::ostringstream grpName; grpName << *grp << "_top";
4447 grpArr2->setName(grpName.str());
4448 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4449 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4450 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4452 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4457 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4458 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4459 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4461 * \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
4462 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4463 * \param [in] eps - detection threshold for coordinates.
4464 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4466 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4468 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4471 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4472 int initialNbNodes(getNumberOfNodes());
4473 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4474 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4476 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4478 DataArrayDouble *zeCoords(m0->getCoords());
4479 ret->setMeshAtLevel(0,m0);
4480 std::vector<int> levs(getNonEmptyLevels());
4481 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4484 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4485 ret->setFamilyFieldArr(0,famFieldCpy);
4487 famField=getFamilyFieldAtLevel(1);
4490 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4491 fam->fillWithZero();
4492 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4493 ret->setFamilyFieldArr(1,fam);
4495 ret->copyFamGrpMapsFrom(*this);
4496 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4497 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4501 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4502 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4503 if(m1->getMeshDimension()!=0)
4506 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4507 }//kill unused notUsed var
4508 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4510 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4511 MCAuto<DataArrayInt> bSafe(b);
4514 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4515 throw INTERP_KERNEL::Exception(oss.str().c_str());
4517 b->applyLin(1,initialNbNodes);
4518 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4519 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4520 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4521 m1->renumberNodesInConn(renum->begin());
4523 m1->setCoords(zeCoords);
4524 ret->setMeshAtLevel(*lev,m1);
4525 famField=getFamilyFieldAtLevel(*lev);
4528 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4529 ret->setFamilyFieldArr(*lev,famFieldCpy);
4536 * This method converts all quadratic cells in \a this into linear cells.
4537 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4538 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4540 * \param [in] eps - detection threshold for coordinates.
4541 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4543 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4545 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4548 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4549 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4550 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4551 m0->convertQuadraticCellsToLinear();
4553 DataArrayDouble *zeCoords(m0->getCoords());
4554 ret->setMeshAtLevel(0,m0);
4555 std::vector<int> levs(getNonEmptyLevels());
4556 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4559 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4560 ret->setFamilyFieldArr(0,famFieldCpy);
4562 famField=getFamilyFieldAtLevel(1);
4565 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4566 ret->setFamilyFieldArr(1,fam);
4568 ret->copyFamGrpMapsFrom(*this);
4569 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4573 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4574 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4575 m1->convertQuadraticCellsToLinear();
4578 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4579 MCAuto<DataArrayInt> bSafe(b);
4582 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4583 throw INTERP_KERNEL::Exception(oss.str().c_str());
4585 m1->renumberNodesInConn(b->begin());
4586 m1->setCoords(zeCoords);
4587 ret->setMeshAtLevel(*lev,m1);
4588 famField=getFamilyFieldAtLevel(*lev);
4591 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4592 ret->setFamilyFieldArr(*lev,famFieldCpy);
4599 * Computes the symmetry of \a this.
4600 * \return a new object.
4602 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4604 MCAuto<MEDFileUMesh> ret(deepCopy());
4605 DataArrayDouble *myCoo(getCoords());
4608 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4609 ret->setCoordsForced(newCoo);
4614 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4617 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4618 std::size_t sz(meshes.size()),i(0);
4619 std::vector<const DataArrayDouble *> coos(sz);
4620 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4621 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4624 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4625 coos[i]=(*it)->getCoords();
4626 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4627 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4629 const MEDFileUMesh *ref(meshes[0]);
4630 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4631 std::vector<int> levs(ref->getNonEmptyLevels());
4632 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4633 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4634 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4635 std::map<std::string,int> map1;
4636 std::map<std::string, std::vector<std::string> > map2;
4637 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4639 if((*it)->getSpaceDimension()!=spaceDim)
4640 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4641 if((*it)->getMeshDimension()!=meshDim)
4642 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4643 if((*it)->getNonEmptyLevels()!=levs)
4644 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4645 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4647 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4648 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4649 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4650 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4652 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4653 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4654 map1[(*it3).first]=(*it3).second;
4655 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4656 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4657 map2[(*it4).first]=(*it4).second;
4659 // Easy part : nodes
4660 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4661 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4662 ret->setCoords(coo);
4663 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4665 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4666 ret->setFamilyFieldArr(1,fam_coo);
4668 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4670 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4671 ret->setRenumFieldArr(1,num_coo);
4674 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4676 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4677 if(it2==m_mesh.end())
4678 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4679 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4680 mesh->setCoords(coo); mesh->setName(ref->getName());
4681 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4682 ret->setMeshAtLevel(*it,mesh);
4683 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4684 if(it3!=m_fam.end())
4686 const std::vector<const DataArrayInt *>& fams((*it3).second);
4687 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4689 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4690 famm->renumberInPlace(renum->begin());
4691 ret->setFamilyFieldArr(*it,famm);
4694 if(it4!=m_renum.end())
4696 const std::vector<const DataArrayInt *>& renums((*it4).second);
4697 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4699 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4700 renumm->renumberInPlace(renum->begin());
4701 ret->setRenumFieldArr(*it,renumm);
4706 ret->setFamilyInfo(map1);
4707 ret->setGroupInfo(map2);
4708 ret->setName(ref->getName());
4712 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4714 if(getMeshDimension()!=3)
4715 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4716 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4717 if(m3D.isNull() || m2D.isNull())
4718 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4719 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4720 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4724 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4726 clearNonDiscrAttributes();
4727 forceComputationOfParts();
4728 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4729 std::vector<int> layer0;
4730 layer0.push_back(getAxisType());//0 i
4731 layer0.push_back(_order); //1 i
4732 layer0.push_back(_iteration);//2 i
4733 layer0.push_back(getSpaceDimension());//3 i
4734 tinyDouble.push_back(_time);//0 d
4735 tinyStr.push_back(_name);//0 s
4736 tinyStr.push_back(_desc_name);//1 s
4737 for(int i=0;i<getSpaceDimension();i++)
4738 tinyStr.push_back(_coords->getInfoOnComponent(i));
4739 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4740 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4742 tinyStr.push_back((*it).first);
4743 layer0.push_back((*it).second);
4745 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4746 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4748 layer0.push_back((int)(*it0).second.size());
4749 tinyStr.push_back((*it0).first);
4750 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4751 tinyStr.push_back(*it1);
4753 // sizeof(layer0)==4+aa+1+bb layer#0
4754 bigArrayD=_coords;// 0 bd
4755 bigArraysI.push_back(_fam_coords);// 0 bi
4756 bigArraysI.push_back(_num_coords);// 1 bi
4757 const PartDefinition *pd(_part_coords);
4759 layer0.push_back(-1);
4762 std::vector<int> tmp0;
4763 pd->serialize(tmp0,bigArraysI);
4764 tinyInt.push_back(tmp0.size());
4765 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4768 std::vector<int> layer1;
4769 std::vector<int> levs(getNonEmptyLevels());
4770 layer1.push_back((int)levs.size());// 0 i <- key
4771 layer1.insert(layer1.end(),levs.begin(),levs.end());
4772 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4774 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4775 lev->serialize(layer1,bigArraysI);
4777 // put layers all together.
4778 tinyInt.push_back(layer0.size());
4779 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4780 tinyInt.push_back(layer1.size());
4781 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4784 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4785 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4787 int sz0(tinyInt[0]);
4788 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4789 int sz1(tinyInt[sz0+1]);
4790 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4792 std::reverse(layer0.begin(),layer0.end());
4793 std::reverse(layer1.begin(),layer1.end());
4794 std::reverse(tinyDouble.begin(),tinyDouble.end());
4795 std::reverse(tinyStr.begin(),tinyStr.end());
4796 std::reverse(bigArraysI.begin(),bigArraysI.end());
4798 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4799 _order=layer0.back(); layer0.pop_back();
4800 _iteration=layer0.back(); layer0.pop_back();
4801 int spaceDim(layer0.back()); layer0.pop_back();
4802 _time=tinyDouble.back(); tinyDouble.pop_back();
4803 _name=tinyStr.back(); tinyStr.pop_back();
4804 _desc_name=tinyStr.back(); tinyStr.pop_back();
4805 _coords=bigArrayD; _coords->rearrange(spaceDim);
4806 for(int i=0;i<spaceDim;i++)
4808 _coords->setInfoOnComponent(i,tinyStr.back());
4811 int nbOfFams(layer0.back()); layer0.pop_back();
4813 for(int i=0;i<nbOfFams;i++)
4815 _families[tinyStr.back()]=layer0.back();
4816 tinyStr.pop_back(); layer0.pop_back();
4818 int nbGroups(layer0.back()); layer0.pop_back();
4820 for(int i=0;i<nbGroups;i++)
4822 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4823 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4824 std::vector<std::string> fams(nbOfFamsOnGrp);
4825 for(int j=0;j<nbOfFamsOnGrp;j++)
4827 fams[j]=tinyStr.back(); tinyStr.pop_back();
4829 _groups[grpName]=fams;
4831 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4832 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4834 int isPd(layer0.back()); layer0.pop_back();
4837 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4838 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4839 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4842 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4844 int nbLevs(layer1.back()); layer1.pop_back();
4845 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4847 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4848 _ms.resize(maxLev+1);
4849 for(int i=0;i<nbLevs;i++)
4853 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4858 * Adds a group of nodes to \a this mesh.
4859 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4860 * The ids should be sorted and different each other (MED file norm).
4862 * \warning this method can alter default "FAMILLE_ZERO" family.
4863 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4865 * \throw If the node coordinates array is not set.
4866 * \throw If \a ids == \c NULL.
4867 * \throw If \a ids->getName() == "".
4868 * \throw If \a ids does not respect the MED file norm.
4869 * \throw If a group with name \a ids->getName() already exists.
4871 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4873 const DataArrayDouble *coords(_coords);
4875 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4876 int nbOfNodes(coords->getNumberOfTuples());
4877 if(!((DataArrayInt *)_fam_coords))
4878 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4880 addGroupUnderground(true,ids,_fam_coords);
4884 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4886 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4887 * The ids should be sorted and different each other (MED file norm).
4889 * \warning this method can alter default "FAMILLE_ZERO" family.
4890 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4892 * \throw If the node coordinates array is not set.
4893 * \throw If \a ids == \c NULL.
4894 * \throw If \a ids->getName() == "".
4895 * \throw If \a ids does not respect the MED file norm.
4896 * \throw If a group with name \a ids->getName() already exists.
4898 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4900 std::vector<int> levs(getNonEmptyLevelsExt());
4901 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4903 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4904 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4906 if(meshDimRelToMaxExt==1)
4907 { addNodeGroup(ids); return ; }
4908 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4909 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4910 addGroupUnderground(false,ids,fam);
4914 * Changes a name of a family specified by its id.
4915 * \param [in] id - the id of the family of interest.
4916 * \param [in] newFamName - the new family name.
4917 * \throw If no family with the given \a id exists.
4919 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4921 std::string oldName=getFamilyNameGivenId(id);
4922 _families.erase(oldName);
4923 _families[newFamName]=id;
4927 * Removes a mesh of a given dimension.
4928 * \param [in] meshDimRelToMax - the relative dimension of interest.
4929 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4931 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4933 std::vector<int> levSet=getNonEmptyLevels();
4934 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4935 if(it==levSet.end())
4936 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4937 int pos=(-meshDimRelToMax);
4942 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4943 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4944 * \param [in] m - the new mesh to set.
4945 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4947 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4948 * another node coordinates array.
4949 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4950 * to the existing meshes of other levels of \a this mesh.
4952 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4954 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4955 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4959 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4960 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4961 * \param [in] m - the new mesh to set.
4962 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4963 * writing \a this mesh in a MED file.
4964 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4966 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4967 * another node coordinates array.
4968 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4969 * to the existing meshes of other levels of \a this mesh.
4971 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4973 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4974 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4977 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4979 dealWithTinyInfo(m);
4980 std::vector<int> levSet=getNonEmptyLevels();
4981 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4983 if((DataArrayDouble *)_coords==0)
4985 DataArrayDouble *c=m->getCoords();
4990 if(m->getCoords()!=_coords)
4991 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4992 int sz=(-meshDimRelToMax)+1;
4993 if(sz>=(int)_ms.size())
4995 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4999 return _ms[-meshDimRelToMax];
5003 * This method allows to set at once the content of different levels in \a this.
5004 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5006 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5007 * \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.
5008 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
5010 * \throw If \a there is a null pointer in \a ms.
5011 * \sa MEDFileUMesh::setMeshAtLevel
5013 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5017 const MEDCouplingUMesh *mRef=ms[0];
5019 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5020 std::string name(mRef->getName());
5021 const DataArrayDouble *coo(mRef->getCoords());
5024 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5026 const MEDCouplingUMesh *cur(*it);
5028 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5029 if(coo!=cur->getCoords())
5030 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5031 int mdim=cur->getMeshDimension();
5032 zeDim=std::max(zeDim,mdim);
5033 if(s.find(mdim)!=s.end())
5034 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5036 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5038 int mdim=(*it)->getMeshDimension();
5039 setName((*it)->getName());
5040 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5046 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5047 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5048 * The given meshes must share the same node coordinates array.
5049 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5050 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5051 * create in \a this mesh.
5052 * \throw If \a ms is empty.
5053 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5054 * to the existing meshes of other levels of \a this mesh.
5055 * \throw If the meshes in \a ms do not share the same node coordinates array.
5056 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5057 * of the given meshes.
5058 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5059 * \throw If names of some meshes in \a ms are equal.
5060 * \throw If \a ms includes a mesh with an empty name.
5062 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5065 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5066 int sz=(-meshDimRelToMax)+1;
5067 if(sz>=(int)_ms.size())
5069 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5070 DataArrayDouble *coo=checkMultiMesh(ms);
5071 if((DataArrayDouble *)_coords==0)
5077 if((DataArrayDouble *)_coords!=coo)
5078 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5079 std::vector<DataArrayInt *> corr;
5080 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5081 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5082 setMeshAtLevel(meshDimRelToMax,m,renum);
5083 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5084 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5088 * Creates groups at a given level in \a this mesh from a sequence of
5089 * meshes each representing a group.
5090 * The given meshes must share the same node coordinates array.
5091 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5092 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5093 * create in \a this mesh.
5094 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5096 * \throw If \a ms is empty.
5097 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5098 * to the existing meshes of other levels of \a this mesh.
5099 * \throw If the meshes in \a ms do not share the same node coordinates array.
5100 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5101 * of the given meshes.
5102 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5103 * \throw If names of some meshes in \a ms are equal.
5104 * \throw If \a ms includes a mesh with an empty name.
5106 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5109 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5110 int sz=(-meshDimRelToMax)+1;
5111 if(sz>=(int)_ms.size())
5113 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5114 DataArrayDouble *coo=checkMultiMesh(ms);
5115 if((DataArrayDouble *)_coords==0)
5121 if((DataArrayDouble *)_coords!=coo)
5122 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5123 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5124 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5126 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5128 DataArrayInt *arr=0;
5129 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5133 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5134 throw INTERP_KERNEL::Exception(oss.str().c_str());
5137 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5138 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5141 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5143 const DataArrayDouble *ret=ms[0]->getCoords();
5144 int mdim=ms[0]->getMeshDimension();
5145 for(unsigned int i=1;i<ms.size();i++)
5147 ms[i]->checkConsistencyLight();
5148 if(ms[i]->getCoords()!=ret)
5149 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5150 if(ms[i]->getMeshDimension()!=mdim)
5151 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5153 return const_cast<DataArrayDouble *>(ret);
5157 * Sets the family field of a given relative dimension.
5158 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5159 * the family field is set.
5160 * \param [in] famArr - the array of the family field.
5161 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5162 * \throw If \a famArr has an invalid size.
5164 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5166 if(meshDimRelToMaxExt==1)
5173 DataArrayDouble *coo(_coords);
5175 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5176 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5177 _fam_coords.takeRef(famArr);
5180 if(meshDimRelToMaxExt>1)
5181 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5182 int traducedRk=-meshDimRelToMaxExt;
5183 if(traducedRk>=(int)_ms.size())
5184 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5185 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5186 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5187 return _ms[traducedRk]->setFamilyArr(famArr);
5191 * Sets the optional numbers of mesh entities of a given dimension.
5192 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5193 * \param [in] renumArr - the array of the numbers.
5194 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5195 * \throw If \a renumArr has an invalid size.
5197 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5199 if(meshDimRelToMaxExt==1)
5203 _num_coords.nullify();
5204 _rev_num_coords.nullify();
5207 if(_coords.isNull())
5208 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5209 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5210 _num_coords.takeRef(renumArr);
5214 if(meshDimRelToMaxExt>1)
5215 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5216 int traducedRk=-meshDimRelToMaxExt;
5217 if(traducedRk>=(int)_ms.size())
5218 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5219 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5220 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5221 return _ms[traducedRk]->setRenumArr(renumArr);
5225 * Sets the optional names of mesh entities of a given dimension.
5226 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5227 * \param [in] nameArr - the array of the names.
5228 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5229 * \throw If \a nameArr has an invalid size.
5231 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5233 if(meshDimRelToMaxExt==1)
5240 DataArrayDouble *coo(_coords);
5242 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5243 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5244 _name_coords.takeRef(nameArr);
5247 if(meshDimRelToMaxExt>1)
5248 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5249 int traducedRk=-meshDimRelToMaxExt;
5250 if(traducedRk>=(int)_ms.size())
5251 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5252 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5253 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5254 return _ms[traducedRk]->setNameArr(nameArr);
5257 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5259 if(meshDimRelToMaxExt!=1)
5260 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5262 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5263 _global_num_coords.takeRef(globalNumArr);
5266 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5268 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5269 if((const MEDFileUMeshSplitL1 *)(*it))
5270 (*it)->synchronizeTinyInfo(*this);
5274 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5276 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5278 DataArrayInt *arr=_fam_coords;
5280 arr->changeValue(oldId,newId);
5281 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5283 MEDFileUMeshSplitL1 *sp=(*it);
5286 sp->changeFamilyIdArr(oldId,newId);
5291 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5293 std::list< MCAuto<DataArrayInt> > ret;
5294 const DataArrayInt *da(_fam_coords);
5296 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5297 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5299 const MEDFileUMeshSplitL1 *elt(*it);
5302 da=elt->getFamilyField();
5304 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5310 void MEDFileUMesh::computeRevNum() const
5312 if(_num_coords.isNotNull())
5315 int maxValue=_num_coords->getMaxValue(pos);
5316 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5320 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5322 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5325 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5327 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5328 ret.push_back((const DataArrayInt *)_fam_nodes);
5329 ret.push_back((const DataArrayInt *)_num_nodes);
5330 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5331 ret.push_back((const DataArrayInt *)_fam_cells);
5332 ret.push_back((const DataArrayInt *)_num_cells);
5333 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5334 ret.push_back((const DataArrayInt *)_fam_faces);
5335 ret.push_back((const DataArrayInt *)_num_faces);
5336 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5337 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5338 ret.push_back((const DataArrayInt *)_rev_num_cells);
5339 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5343 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5345 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5346 if((const DataArrayInt *)_fam_nodes)
5348 int val=_fam_nodes->getMaxValue(tmp);
5349 ret=std::max(ret,std::abs(val));
5351 if((const DataArrayInt *)_fam_cells)
5353 int val=_fam_cells->getMaxValue(tmp);
5354 ret=std::max(ret,std::abs(val));
5356 if((const DataArrayInt *)_fam_faces)
5358 int val=_fam_faces->getMaxValue(tmp);
5359 ret=std::max(ret,std::abs(val));
5364 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5366 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5367 if((const DataArrayInt *)_fam_nodes)
5369 int val=_fam_nodes->getMaxValue(tmp);
5370 ret=std::max(ret,val);
5372 if((const DataArrayInt *)_fam_cells)
5374 int val=_fam_cells->getMaxValue(tmp);
5375 ret=std::max(ret,val);
5377 if((const DataArrayInt *)_fam_faces)
5379 int val=_fam_faces->getMaxValue(tmp);
5380 ret=std::max(ret,val);
5385 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5387 int ret=std::numeric_limits<int>::max(),tmp=-1;
5388 if((const DataArrayInt *)_fam_nodes)
5390 int val=_fam_nodes->getMinValue(tmp);
5391 ret=std::min(ret,val);
5393 if((const DataArrayInt *)_fam_cells)
5395 int val=_fam_cells->getMinValue(tmp);
5396 ret=std::min(ret,val);
5398 if((const DataArrayInt *)_fam_faces)
5400 int val=_fam_faces->getMinValue(tmp);
5401 ret=std::min(ret,val);
5406 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5408 if(!MEDFileMesh::isEqual(other,eps,what))
5410 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5413 what="Mesh types differ ! This is structured and other is NOT !";
5416 const DataArrayInt *famc1=_fam_nodes;
5417 const DataArrayInt *famc2=otherC->_fam_nodes;
5418 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5420 what="Mismatch of families arr on nodes ! One is defined and not other !";
5425 bool ret=famc1->isEqual(*famc2);
5428 what="Families arr on nodes differ !";
5433 famc2=otherC->_fam_cells;
5434 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5436 what="Mismatch of families arr on cells ! One is defined and not other !";
5441 bool ret=famc1->isEqual(*famc2);
5444 what="Families arr on cells differ !";
5449 famc2=otherC->_fam_faces;
5450 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5452 what="Mismatch of families arr on faces ! One is defined and not other !";
5457 bool ret=famc1->isEqual(*famc2);
5460 what="Families arr on faces differ !";
5465 famc2=otherC->_num_nodes;
5466 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5468 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5473 bool ret=famc1->isEqual(*famc2);
5476 what="Numbering arr on nodes differ !";
5481 famc2=otherC->_num_cells;
5482 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5484 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5489 bool ret=famc1->isEqual(*famc2);
5492 what="Numbering arr on cells differ !";
5497 famc2=otherC->_num_faces;
5498 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5500 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5505 bool ret=famc1->isEqual(*famc2);
5508 what="Numbering arr on faces differ !";
5512 const DataArrayAsciiChar *d1=_names_cells;
5513 const DataArrayAsciiChar *d2=otherC->_names_cells;
5514 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5516 what="Mismatch of naming arr on cells ! One is defined and not other !";
5521 bool ret=d1->isEqual(*d2);
5524 what="Naming arr on cells differ !";
5529 d2=otherC->_names_faces;
5530 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5532 what="Mismatch of naming arr on faces ! One is defined and not other !";
5537 bool ret=d1->isEqual(*d2);
5540 what="Naming arr on faces differ !";
5545 d2=otherC->_names_nodes;
5546 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5548 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5553 bool ret=d1->isEqual(*d2);
5556 what="Naming arr on nodes differ !";
5563 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5565 MEDFileMesh::clearNonDiscrAttributes();
5566 const DataArrayInt *tmp=_fam_nodes;
5568 (const_cast<DataArrayInt *>(tmp))->setName("");
5571 (const_cast<DataArrayInt *>(tmp))->setName("");
5574 (const_cast<DataArrayInt *>(tmp))->setName("");
5577 (const_cast<DataArrayInt *>(tmp))->setName("");
5580 (const_cast<DataArrayInt *>(tmp))->setName("");
5583 (const_cast<DataArrayInt *>(tmp))->setName("");
5587 * Returns ids of mesh entities contained in given families of a given dimension.
5588 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5590 * \param [in] fams - the names of the families of interest.
5591 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5592 * returned instead of ids.
5593 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5594 * numbers, if available and required, of mesh entities of the families. The caller
5595 * is to delete this array using decrRef() as it is no more needed.
5596 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5598 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5600 std::vector<int> famIds(getFamiliesIds(fams));
5601 switch(meshDimRelToMaxExt)
5605 if((const DataArrayInt *)_fam_nodes)
5607 MCAuto<DataArrayInt> da;
5609 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5611 da=_fam_nodes->findIdsEqualList(0,0);
5613 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5618 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5623 if((const DataArrayInt *)_fam_cells)
5625 MCAuto<DataArrayInt> da;
5627 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5629 da=_fam_cells->findIdsEqualList(0,0);
5631 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5636 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5641 if((const DataArrayInt *)_fam_faces)
5643 MCAuto<DataArrayInt> da;
5645 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5647 da=_fam_faces->findIdsEqualList(0,0);
5649 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5654 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5658 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5660 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5664 * Sets the family field of a given relative dimension.
5665 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5666 * the family field is set.
5667 * \param [in] famArr - the array of the family field.
5668 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5669 * \throw If \a famArr has an invalid size.
5670 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5672 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5674 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5676 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5677 switch(meshDimRelToMaxExt)
5681 int nbCells(mesh->getNumberOfCells());
5683 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5689 int nbNodes(mesh->getNumberOfNodes());
5691 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5697 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5699 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5704 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5711 * Sets the optional numbers of mesh entities of a given dimension.
5712 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5713 * \param [in] renumArr - the array of the numbers.
5714 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5715 * \throw If \a renumArr has an invalid size.
5716 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5718 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5720 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5722 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5723 switch(meshDimRelToMaxExt)
5727 int nbCells=mesh->getNumberOfCells();
5728 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5729 _num_cells=renumArr;
5734 int nbNodes=mesh->getNumberOfNodes();
5735 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5736 _num_nodes=renumArr;
5741 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5742 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5743 _num_faces=renumArr;
5747 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5750 renumArr->incrRef();
5754 * Sets the optional names of mesh entities of a given dimension.
5755 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5756 * \param [in] nameArr - the array of the names.
5757 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5758 * \throw If \a nameArr has an invalid size.
5760 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5762 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5764 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5765 switch(meshDimRelToMaxExt)
5769 int nbCells=mesh->getNumberOfCells();
5770 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5771 _names_cells=nameArr;
5776 int nbNodes=mesh->getNumberOfNodes();
5777 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5778 _names_nodes=nameArr;
5783 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5784 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5785 _names_cells=nameArr;
5788 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5794 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5796 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
5800 * Adds a group of nodes to \a this mesh.
5801 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5802 * The ids should be sorted and different each other (MED file norm).
5804 * \warning this method can alter default "FAMILLE_ZERO" family.
5805 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5807 * \throw If the node coordinates array is not set.
5808 * \throw If \a ids == \c NULL.
5809 * \throw If \a ids->getName() == "".
5810 * \throw If \a ids does not respect the MED file norm.
5811 * \throw If a group with name \a ids->getName() already exists.
5813 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5819 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5821 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5822 * The ids should be sorted and different each other (MED file norm).
5824 * \warning this method can alter default "FAMILLE_ZERO" family.
5825 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5827 * \throw If the node coordinates array is not set.
5828 * \throw If \a ids == \c NULL.
5829 * \throw If \a ids->getName() == "".
5830 * \throw If \a ids does not respect the MED file norm.
5831 * \throw If a group with name \a ids->getName() already exists.
5833 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5835 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5836 addGroupUnderground(false,ids,fam);
5841 * Returns the family field for mesh entities of a given dimension.
5842 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5843 * \return const DataArrayInt * - the family field. It is an array of ids of families
5844 * each mesh entity belongs to. It can be \c NULL.
5845 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5847 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5849 switch(meshDimRelToMaxExt)
5858 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5863 * Returns the family field for mesh entities of a given dimension.
5864 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5865 * \return const DataArrayInt * - the family field. It is an array of ids of families
5866 * each mesh entity belongs to. It can be \c NULL.
5867 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5869 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5871 switch(meshDimRelToMaxExt)
5880 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5885 * Returns the optional numbers of mesh entities of a given dimension.
5886 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5887 * \return const DataArrayInt * - the array of the entity numbers.
5888 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5889 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5891 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5893 switch(meshDimRelToMaxExt)
5902 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5907 * Returns the optional numbers of mesh entities of a given dimension transformed using
5908 * DataArrayInt::invertArrayN2O2O2N().
5909 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5910 * \return const DataArrayInt * - the array of the entity numbers transformed using
5911 * DataArrayInt::invertArrayN2O2O2N().
5912 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5913 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5915 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5917 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5918 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5919 if(meshDimRelToMaxExt==0)
5921 if((const DataArrayInt *)_num_cells)
5924 int maxValue=_num_cells->getMaxValue(pos);
5925 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5926 return _rev_num_cells;
5929 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5933 if((const DataArrayInt *)_num_nodes)
5936 int maxValue=_num_nodes->getMaxValue(pos);
5937 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5938 return _rev_num_nodes;
5941 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5945 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5947 switch(meshDimRelToMaxExt)
5950 return _names_cells;
5952 return _names_nodes;
5954 return _names_faces;
5956 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5960 MCAuto<DataArrayInt> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
5962 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
5966 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5967 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5969 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5971 std::vector<int> ret(1);
5976 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5977 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5979 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5981 std::vector<int> ret(2);
5987 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5989 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5991 std::vector<int> ret;
5992 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6003 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6005 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6007 std::vector<int> ret;
6008 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6019 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6021 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6023 std::vector<int> ret;
6024 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6035 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6037 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
6039 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6043 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
6045 DataArrayInt *arr=_fam_nodes;
6047 arr->changeValue(oldId,newId);
6050 arr->changeValue(oldId,newId);
6053 arr->changeValue(oldId,newId);
6056 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6058 std::list< MCAuto<DataArrayInt> > ret;
6059 const DataArrayInt *da(_fam_nodes);
6061 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6064 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6067 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6071 void MEDFileStructuredMesh::deepCpyAttributes()
6073 if((const DataArrayInt*)_fam_nodes)
6074 _fam_nodes=_fam_nodes->deepCopy();
6075 if((const DataArrayInt*)_num_nodes)
6076 _num_nodes=_num_nodes->deepCopy();
6077 if((const DataArrayAsciiChar*)_names_nodes)
6078 _names_nodes=_names_nodes->deepCopy();
6079 if((const DataArrayInt*)_fam_cells)
6080 _fam_cells=_fam_cells->deepCopy();
6081 if((const DataArrayInt*)_num_cells)
6082 _num_cells=_num_cells->deepCopy();
6083 if((const DataArrayAsciiChar*)_names_cells)
6084 _names_cells=_names_cells->deepCopy();
6085 if((const DataArrayInt*)_fam_faces)
6086 _fam_faces=_fam_faces->deepCopy();
6087 if((const DataArrayInt*)_num_faces)
6088 _num_faces=_num_faces->deepCopy();
6089 if((const DataArrayAsciiChar*)_names_faces)
6090 _names_faces=_names_faces->deepCopy();
6091 if((const DataArrayInt*)_rev_num_nodes)
6092 _rev_num_nodes=_rev_num_nodes->deepCopy();
6093 if((const DataArrayInt*)_rev_num_cells)
6094 _rev_num_cells=_rev_num_cells->deepCopy();
6098 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
6100 * \return a pointer to cartesian mesh that need to be managed by the caller.
6101 * \warning the returned pointer has to be managed by the caller.
6105 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6106 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6107 * \param [in] renum - it must be \c false.
6108 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6109 * delete using decrRef() as it is no more needed.
6111 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6115 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6116 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6117 switch(meshDimRelToMax)
6123 return const_cast<MEDCouplingStructuredMesh *>(m);
6128 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6129 buildMinusOneImplicitPartIfNeeded();
6130 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6136 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6140 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6142 std::vector<int> ret;
6143 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6144 if(famCells && famCells->presenceOfValue(ret))
6146 if(famFaces && famFaces->presenceOfValue(ret))
6151 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6153 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6154 const DataArrayInt *famNodes(_fam_nodes);
6155 if(famNodes && famNodes->presenceOfValue(ret))
6161 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6162 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6163 * \return int - the number of entities.
6164 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6166 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6168 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6170 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6171 switch(meshDimRelToMaxExt)
6174 return cmesh->getNumberOfCells();
6176 return cmesh->getNumberOfNodes();
6178 return cmesh->getNumberOfCellsOfSubLevelMesh();
6180 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6184 int MEDFileStructuredMesh::getNumberOfNodes() const
6186 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6188 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6189 return cmesh->getNumberOfNodes();
6192 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6194 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6196 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6197 switch(meshDimRelToMaxExt)
6200 return cmesh->getNumberOfCells();
6202 return cmesh->getNumberOfCellsOfSubLevelMesh();
6204 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6208 bool MEDFileStructuredMesh::hasImplicitPart() const
6214 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6216 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6218 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6219 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6222 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6223 if(cm.getReverseExtrudedType()!=gt)
6224 throw INTERP_KERNEL::Exception(MSG);
6225 buildImplicitPart();
6226 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6230 if(gt!=zeFaceMesh->getCellModelEnum())
6231 throw INTERP_KERNEL::Exception(MSG);
6232 return zeFaceMesh->getNumberOfCells();
6236 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6238 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6240 buildImplicitPart();
6243 void MEDFileStructuredMesh::buildImplicitPart() const
6245 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6247 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6248 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6251 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6253 _faces_if_necessary=0;
6257 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6258 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6260 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6262 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6265 return _faces_if_necessary;
6268 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6270 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6272 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6273 switch(meshDimRelToMax)
6277 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6282 int mdim(cmesh->getMeshDimension());
6284 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6285 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6289 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6293 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6295 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6298 return getNumberOfCellsAtLevel(0);
6301 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6303 if(st.getNumberOfItems()!=1)
6304 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 !");
6305 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6306 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6307 if(getNumberOfNodes()!=(int)nodesFetched.size())
6308 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6309 if(st[0].getPflName().empty())
6311 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6314 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6315 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6316 int sz(nodesFetched.size());
6317 for(const int *work=arr->begin();work!=arr->end();work++)
6319 std::vector<int> conn;
6320 cmesh->getNodeIdsOfCell(*work,conn);
6321 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6322 if(*it>=0 && *it<sz)
6323 nodesFetched[*it]=true;
6325 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6329 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6331 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6335 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6336 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6338 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6339 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6341 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6344 if(!mrs || mrs->isCellFamilyFieldReading())
6346 famCells=DataArrayInt::New();
6347 famCells->alloc(nbOfElt,1);
6348 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6351 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6354 if(!mrs || mrs->isCellNumFieldReading())
6356 numCells=DataArrayInt::New();
6357 numCells->alloc(nbOfElt,1);
6358 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6361 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6364 if(!mrs || mrs->isCellNameFieldReading())
6366 namesCells=DataArrayAsciiChar::New();
6367 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6368 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6369 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6374 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6376 setName(strm->getName());
6377 setDescription(strm->getDescription());
6378 setUnivName(strm->getUnivName());
6379 setIteration(strm->getIteration());
6380 setOrder(strm->getOrder());
6381 setTimeValue(strm->getTime());
6382 setTimeUnit(strm->getTimeUnit());
6383 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6384 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6385 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6388 if(!mrs || mrs->isNodeFamilyFieldReading())
6390 int nbNodes(getNumberOfNodes());
6392 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6393 _fam_nodes=DataArrayInt::New();
6394 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6395 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...
6396 _fam_nodes->fillWithZero();
6397 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6400 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6403 if(!mrs || mrs->isNodeNumFieldReading())
6405 _num_nodes=DataArrayInt::New();
6406 _num_nodes->alloc(nbOfElt,1);
6407 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6410 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6413 if(!mrs || mrs->isNodeNameFieldReading())
6415 _names_nodes=DataArrayAsciiChar::New();
6416 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6417 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6418 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6421 int meshDim(getStructuredMesh()->getMeshDimension());
6422 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6424 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6427 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6429 int meshDim(getStructuredMesh()->getMeshDimension());
6430 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6432 if((const DataArrayInt *)_fam_cells)
6433 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6434 if((const DataArrayInt *)_fam_faces)
6435 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6436 if((const DataArrayInt *)_fam_nodes)
6437 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6438 if((const DataArrayInt *)_num_cells)
6439 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6440 if((const DataArrayInt *)_num_faces)
6441 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6442 if((const DataArrayInt *)_num_nodes)
6443 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6444 if((const DataArrayAsciiChar *)_names_cells)
6446 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6448 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6449 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6450 throw INTERP_KERNEL::Exception(oss.str().c_str());
6452 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6454 if((const DataArrayAsciiChar *)_names_faces)
6456 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6458 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6459 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6460 throw INTERP_KERNEL::Exception(oss.str().c_str());
6462 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6464 if((const DataArrayAsciiChar *)_names_nodes)
6466 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6468 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6469 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6470 throw INTERP_KERNEL::Exception(oss.str().c_str());
6472 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6475 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6479 * Returns an empty instance of MEDFileCMesh.
6480 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6481 * mesh using decrRef() as it is no more needed.
6483 MEDFileCMesh *MEDFileCMesh::New()
6485 return new MEDFileCMesh;
6489 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6490 * file. The first mesh in the file is loaded.
6491 * \param [in] fileName - the name of MED file to read.
6492 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6493 * mesh using decrRef() as it is no more needed.
6494 * \throw If the file is not readable.
6495 * \throw If there is no meshes in the file.
6496 * \throw If the mesh in the file is not a Cartesian one.
6498 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6500 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6501 return New(fid,mrs);
6504 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6506 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6510 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6511 * file. The mesh to load is specified by its name and numbers of a time step and an
6513 * \param [in] fileName - the name of MED file to read.
6514 * \param [in] mName - the name of the mesh to read.
6515 * \param [in] dt - the number of a time step.
6516 * \param [in] it - the number of an iteration.
6517 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6518 * mesh using decrRef() as it is no more needed.
6519 * \throw If the file is not readable.
6520 * \throw If there is no mesh with given attributes in the file.
6521 * \throw If the mesh in the file is not a Cartesian one.
6523 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6525 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6526 return New(fid,mName,dt,it,mrs);
6529 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6531 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6534 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6536 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6539 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6541 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6542 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6547 * Returns the dimension on cells in \a this mesh.
6548 * \return int - the mesh dimension.
6549 * \throw If there are no cells in this mesh.
6551 int MEDFileCMesh::getMeshDimension() const
6553 if(!((const MEDCouplingCMesh*)_cmesh))
6554 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6555 return _cmesh->getMeshDimension();
6559 * Returns the dimension on nodes in \a this mesh.
6560 * \return int - the space dimension.
6561 * \throw If there are no cells in this mesh.
6563 int MEDFileCMesh::getSpaceDimension() const
6565 if(!((const MEDCouplingCMesh*)_cmesh))
6566 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6567 return _cmesh->getSpaceDimension();
6571 * Returns a string describing \a this mesh.
6572 * \return std::string - the mesh information string.
6574 std::string MEDFileCMesh::simpleRepr() const
6576 return MEDFileStructuredMesh::simpleRepr();
6580 * Returns a full textual description of \a this mesh.
6581 * \return std::string - the string holding the mesh description.
6583 std::string MEDFileCMesh::advancedRepr() const
6585 return simpleRepr();
6588 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6590 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6594 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6596 return new MEDFileCMesh;
6599 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6601 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6602 ret->deepCpyEquivalences(*this);
6603 if((const MEDCouplingCMesh*)_cmesh)
6604 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6605 ret->deepCpyAttributes();
6610 * Checks if \a this and another mesh are equal.
6611 * \param [in] other - the mesh to compare with.
6612 * \param [in] eps - a precision used to compare real values.
6613 * \param [in,out] what - the string returning description of unequal data.
6614 * \return bool - \c true if the meshes are equal, \c false, else.
6616 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6618 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6620 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6623 what="Mesh types differ ! This is cartesian and other is NOT !";
6626 clearNonDiscrAttributes();
6627 otherC->clearNonDiscrAttributes();
6628 const MEDCouplingCMesh *coo1=_cmesh;
6629 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6630 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6632 what="Mismatch of cartesian meshes ! One is defined and not other !";
6637 bool ret=coo1->isEqual(coo2,eps);
6640 what="cartesian meshes differ !";
6648 * Clears redundant attributes of incorporated data arrays.
6650 void MEDFileCMesh::clearNonDiscrAttributes() const
6652 MEDFileStructuredMesh::clearNonDiscrAttributes();
6653 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6656 MEDFileCMesh::MEDFileCMesh()
6660 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6663 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6665 catch(INTERP_KERNEL::Exception& e)
6670 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6672 MEDCoupling::MEDCouplingMeshType meshType;
6675 MEDCoupling::MEDCouplingAxisType axType;
6676 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6677 if(meshType!=CARTESIAN)
6679 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6680 throw INTERP_KERNEL::Exception(oss.str().c_str());
6682 MEDFileCMeshL2 loaderl2;
6683 loaderl2.loadAll(fid,mid,mName,dt,it);
6684 setAxisType(axType);
6685 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6688 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6692 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6693 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6695 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6697 synchronizeTinyInfoOnLeaves();
6701 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6703 synchronizeTinyInfoOnLeaves();
6708 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6709 * \param [in] m - the new MEDCouplingCMesh to refer to.
6710 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6713 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6715 dealWithTinyInfo(m);
6721 MEDFileMesh *MEDFileCMesh::cartesianize() const
6723 if(getAxisType()==AX_CART)
6726 return const_cast<MEDFileCMesh *>(this);
6730 const MEDCouplingCMesh *cmesh(getMesh());
6732 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6733 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6734 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6735 clmesh->setCoords(coords);
6736 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6737 ret->MEDFileStructuredMesh::operator=(*this);
6738 ret->setMesh(clmesh);
6739 ret->setAxisType(AX_CART);
6744 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6746 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6747 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6748 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6749 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6750 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6751 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6752 int spaceDim(_cmesh->getSpaceDimension());
6753 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6754 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6755 for(int i=0;i<spaceDim;i++)
6757 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6759 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6760 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
6761 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
6763 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6765 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6766 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6767 for(int i=0;i<spaceDim;i++)
6769 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6770 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6773 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6774 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6777 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6779 const MEDCouplingCMesh *cmesh=_cmesh;
6782 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6783 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6784 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6785 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6788 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6790 return new MEDFileCurveLinearMesh;
6793 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6795 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6798 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6800 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6801 return New(fid,mrs);
6804 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6806 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6807 return New(fid,mName,dt,it,mrs);
6810 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6812 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6815 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6817 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6820 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6822 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6823 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6827 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6829 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6833 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6835 return new MEDFileCurveLinearMesh;
6838 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6840 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6841 ret->deepCpyEquivalences(*this);
6842 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6843 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6844 ret->deepCpyAttributes();
6848 int MEDFileCurveLinearMesh::getMeshDimension() const
6850 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6851 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6852 return _clmesh->getMeshDimension();
6855 std::string MEDFileCurveLinearMesh::simpleRepr() const
6857 return MEDFileStructuredMesh::simpleRepr();
6860 std::string MEDFileCurveLinearMesh::advancedRepr() const
6862 return simpleRepr();
6865 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6867 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6869 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6872 what="Mesh types differ ! This is curve linear and other is NOT !";
6875 clearNonDiscrAttributes();
6876 otherC->clearNonDiscrAttributes();
6877 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6878 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6879 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6881 what="Mismatch of curve linear meshes ! One is defined and not other !";
6886 bool ret=coo1->isEqual(coo2,eps);
6889 what="curve linear meshes differ !";
6896 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6898 MEDFileStructuredMesh::clearNonDiscrAttributes();
6899 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6902 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6904 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6907 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6908 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6909 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6910 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6913 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6915 synchronizeTinyInfoOnLeaves();
6919 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6921 dealWithTinyInfo(m);
6927 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6929 if(getAxisType()==AX_CART)
6932 return const_cast<MEDFileCurveLinearMesh *>(this);
6936 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6938 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6939 const DataArrayDouble *coords(mesh->getCoords());
6941 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6942 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6943 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6944 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6945 mesh2->setCoords(coordsCart);
6946 ret->setMesh(mesh2);
6947 ret->setAxisType(AX_CART);
6952 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6954 synchronizeTinyInfoOnLeaves();
6958 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6962 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6965 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6967 catch(INTERP_KERNEL::Exception& e)
6972 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
6974 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6975 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6976 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6977 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6978 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6979 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6980 int spaceDim=_clmesh->getSpaceDimension();
6981 int meshDim=_clmesh->getMeshDimension();
6982 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6983 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6984 const DataArrayDouble *coords=_clmesh->getCoords();
6986 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
6987 for(int i=0;i<spaceDim;i++)
6989 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6991 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6992 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
6993 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
6995 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6997 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6998 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6999 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
7000 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
7002 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
7004 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7005 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7008 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7010 MEDCoupling::MEDCouplingMeshType meshType;
7013 MEDCoupling::MEDCouplingAxisType axType;
7014 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7015 setAxisType(axType);
7016 if(meshType!=CURVE_LINEAR)
7018 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7019 throw INTERP_KERNEL::Exception(oss.str().c_str());
7021 MEDFileCLMeshL2 loaderl2;
7022 loaderl2.loadAll(fid,mid,mName,dt,it);
7023 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7026 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7029 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7031 return new MEDFileMeshMultiTS;
7034 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7036 return new MEDFileMeshMultiTS(fid);
7039 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7041 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7045 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7047 return new MEDFileMeshMultiTS(fid,mName);
7050 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7052 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7053 return New(fid,mName);
7056 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7058 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7059 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7061 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7062 if((const MEDFileMesh *)*it)
7063 meshOneTs[i]=(*it)->deepCopy();
7064 ret->_mesh_one_ts=meshOneTs;
7068 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7070 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7073 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7075 std::vector<const BigMemoryObject *> ret;
7076 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7077 ret.push_back((const MEDFileMesh *)*it);
7081 std::string MEDFileMeshMultiTS::getName() const
7083 if(_mesh_one_ts.empty())
7084 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7085 return _mesh_one_ts[0]->getName();
7088 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7090 std::string oldName(getName());
7091 std::vector< std::pair<std::string,std::string> > v(1);
7092 v[0].first=oldName; v[0].second=newMeshName;
7096 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7099 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7101 MEDFileMesh *cur(*it);
7103 ret=cur->changeNames(modifTab) || ret;
7108 void MEDFileMeshMultiTS::cartesianizeMe()
7110 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7112 MEDFileMesh *cur(*it);
7115 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7121 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7123 if(_mesh_one_ts.empty())
7124 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7125 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7128 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7131 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7132 _mesh_one_ts.resize(1);
7133 mesh1TimeStep->incrRef();
7134 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7135 _mesh_one_ts[0]=mesh1TimeStep;
7138 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7140 if ( MEDFileMesh* m = getOneTimeStep() )
7141 return m->getJoints();
7146 * \brief Set Joints that are common to all time-stamps
7148 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7150 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7152 (*it)->setJoints( joints );
7156 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7158 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7159 if((*it).isNotNull())
7160 if((*it)->presenceOfStructureElements())
7165 void MEDFileMeshMultiTS::killStructureElements()
7167 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7168 if((*it).isNotNull())
7169 (*it)->killStructureElements();
7172 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7174 MEDFileJoints *joints(getJoints());
7175 bool jointsWritten(false);
7177 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7179 if ( jointsWritten )
7180 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7182 jointsWritten = true;
7184 (*it)->copyOptionsFrom(*this);
7185 (*it)->writeLL(fid);
7188 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7191 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7193 MEDFileJoints *joints(0);
7194 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7196 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7197 joints = getOneTimeStep()->getJoints();
7199 _mesh_one_ts.clear(); //for the moment to be improved
7200 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7203 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7207 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7210 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7213 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7214 throw INTERP_KERNEL::Exception(oss.str().c_str());
7217 MEDCoupling::MEDCouplingMeshType meshType;
7219 MEDCoupling::MEDCouplingAxisType dummy3;
7220 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7221 loadFromFile(fid,ms.front());
7223 catch(INTERP_KERNEL::Exception& e)
7228 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7231 loadFromFile(fid,mName);
7233 catch(INTERP_KERNEL::Exception& e)
7238 MEDFileMeshes *MEDFileMeshes::New()
7240 return new MEDFileMeshes;
7243 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7245 return new MEDFileMeshes(fid);
7248 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7250 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7254 void MEDFileMeshes::writeLL(med_idt fid) const
7256 checkConsistencyLight();
7257 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7259 (*it)->copyOptionsFrom(*this);
7260 (*it)->writeLL(fid);
7264 // MEDFileMeshes::writ checkConsistencyLight();
7266 int MEDFileMeshes::getNumberOfMeshes() const
7268 return _meshes.size();
7271 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7273 return new MEDFileMeshesIterator(this);
7276 /** Return a borrowed reference (caller is not responsible) */
7277 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7279 if(i<0 || i>=(int)_meshes.size())
7281 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7282 throw INTERP_KERNEL::Exception(oss.str().c_str());
7284 return _meshes[i]->getOneTimeStep();
7287 /** Return a borrowed reference (caller is not responsible) */
7288 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7290 std::vector<std::string> ms=getMeshesNames();
7291 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7294 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7295 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7296 throw INTERP_KERNEL::Exception(oss.str().c_str());
7298 return getMeshAtPos((int)std::distance(ms.begin(),it));
7301 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7303 std::vector<std::string> ret(_meshes.size());
7305 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7307 const MEDFileMeshMultiTS *f=(*it);
7310 ret[i]=f->getName();
7314 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7315 throw INTERP_KERNEL::Exception(oss.str().c_str());
7321 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7324 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7326 MEDFileMeshMultiTS *cur(*it);
7328 ret=cur->changeNames(modifTab) || ret;
7333 void MEDFileMeshes::cartesianizeMe()
7335 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7337 MEDFileMeshMultiTS *cur(*it);
7339 cur->cartesianizeMe();
7343 void MEDFileMeshes::resize(int newSize)
7345 _meshes.resize(newSize);
7348 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7351 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7352 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7353 elt->setOneTimeStep(mesh);
7354 _meshes.push_back(elt);
7357 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7360 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7361 if(i>=(int)_meshes.size())
7362 _meshes.resize(i+1);
7363 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7364 elt->setOneTimeStep(mesh);
7368 void MEDFileMeshes::destroyMeshAtPos(int i)
7370 if(i<0 || i>=(int)_meshes.size())
7372 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7373 throw INTERP_KERNEL::Exception(oss.str().c_str());
7375 _meshes.erase(_meshes.begin()+i);
7378 void MEDFileMeshes::loadFromFile(med_idt fid)
7380 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7382 _meshes.resize(ms.size());
7383 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7384 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7387 MEDFileMeshes::MEDFileMeshes()
7391 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7396 catch(INTERP_KERNEL::Exception& /*e*/)
7400 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7402 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7404 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7405 if((const MEDFileMeshMultiTS *)*it)
7406 meshes[i]=(*it)->deepCopy();
7407 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7408 ret->_meshes=meshes;
7412 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7414 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7417 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7419 std::vector<const BigMemoryObject *> ret;
7420 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7421 ret.push_back((const MEDFileMeshMultiTS *)*it);
7425 std::string MEDFileMeshes::simpleRepr() const
7427 std::ostringstream oss;
7428 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7429 simpleReprWithoutHeader(oss);
7433 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7435 int nbOfMeshes=getNumberOfMeshes();
7436 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7437 std::vector<std::string> mns=getMeshesNames();
7438 for(int i=0;i<nbOfMeshes;i++)
7439 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7442 void MEDFileMeshes::checkConsistencyLight() const
7444 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7446 std::set<std::string> s;
7447 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7449 const MEDFileMeshMultiTS *elt=(*it);
7452 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7453 throw INTERP_KERNEL::Exception(oss.str().c_str());
7455 std::size_t sz=s.size();
7456 s.insert(std::string((*it)->getName()));
7459 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7460 throw INTERP_KERNEL::Exception(oss.str().c_str());
7465 bool MEDFileMeshes::presenceOfStructureElements() const
7467 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7468 if((*it).isNotNull())
7469 if((*it)->presenceOfStructureElements())
7474 void MEDFileMeshes::killStructureElements()
7476 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7477 if((*it).isNotNull())
7478 (*it)->killStructureElements();
7481 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7486 _nb_iter=ms->getNumberOfMeshes();
7490 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7494 MEDFileMesh *MEDFileMeshesIterator::nextt()
7496 if(_iter_id<_nb_iter)
7498 MEDFileMeshes *ms(_ms);
7500 return ms->getMeshAtPos(_iter_id++);
7508 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7510 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7511 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7513 if(geoType==MED_NO_GEOTYPE)
7514 return INTERP_KERNEL::NORM_ERROR;
7515 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7516 throw INTERP_KERNEL::Exception(oss.str());
7518 return typmai2[std::distance(typmai,pos)];
7521 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7531 std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7532 throw INTERP_KERNEL::Exception(oss.str());