1 // Copyright (C) 2007-2019 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 internally 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;
676 void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name)
678 std::map<std::string, std::vector<std::string> >::iterator it(_groups.find(name));
679 std::vector<std::string> grps(getGroupsNames());
680 if(it==_groups.end())
682 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
683 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
684 throw INTERP_KERNEL::Exception(oss.str().c_str());
686 const std::vector<std::string> &famsOnGrp((*it).second);
687 std::vector<int> famIds(getFamiliesIdsOnGroup(name));
688 const DataArrayInt *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt));
691 MCAuto<DataArrayInt> vals(famArr->getDifferentValues());
692 MCAuto<DataArrayInt> famIds2(DataArrayInt::NewFromStdVector(famIds));
693 MCAuto<DataArrayInt> idsToKill(famIds2->buildIntersection(vals));
694 if(idsToKill->empty())
696 std::vector<std::string> newFamsOnGrp;
697 for(std::vector<std::string>::const_iterator it=famsOnGrp.begin();it!=famsOnGrp.end();it++)
699 if(!idsToKill->presenceOfValue(getFamilyId(*it)))
700 newFamsOnGrp.push_back(*it);
702 (*it).second=newFamsOnGrp;
706 * Removes a group from \a this mesh.
707 * \param [in] name - the name of the group to remove.
708 * \throw If no group with such a \a name exists.
710 void MEDFileMesh::removeGroup(const std::string& name)
712 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(name);
713 std::vector<std::string> grps(getGroupsNames());
714 if(it==_groups.end())
716 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
717 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
718 throw INTERP_KERNEL::Exception(oss.str().c_str());
724 * Removes a family from \a this mesh.
725 * \param [in] name - the name of the family to remove.
726 * \throw If no family with such a \a name exists.
728 void MEDFileMesh::removeFamily(const std::string& name)
730 std::string oname(name);
731 std::map<std::string, int >::iterator it=_families.find(oname);
732 std::vector<std::string> fams=getFamiliesNames();
733 if(it==_families.end())
735 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
736 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
737 throw INTERP_KERNEL::Exception(oss.str().c_str());
740 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
742 std::vector<std::string>& v=(*it3).second;
743 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
750 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
751 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
752 * family field whatever its level. This method also suppresses the orphan families.
754 * \return - The list of removed groups names.
756 * \sa MEDFileMesh::removeOrphanFamilies.
758 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
760 removeOrphanFamilies();
761 return removeEmptyGroups();
765 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
766 * 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.
768 * \return - The list of removed families names.
769 * \sa MEDFileMesh::removeOrphanGroups , MEDFileMesh::removeFamiliesReferedByNoGroups
771 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
773 MCAuto<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
774 std::vector<std::string> ret;
775 if(!((DataArrayInt*)allFamIdsInUse))
777 ret=getFamiliesNames();
778 _families.clear(); _groups.clear();
781 std::map<std::string,int> famMap;
782 std::map<std::string, std::vector<std::string> > grps(_groups);
783 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
785 if(allFamIdsInUse->presenceOfValue((*it).second))
786 famMap[(*it).first]=(*it).second;
789 ret.push_back((*it).first);
790 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
791 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
793 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
794 std::vector<std::string>& famv=(*it3).second;
795 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
801 { _families=famMap; _groups=grps; }
806 * 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
807 * this family is orphan or not.
809 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
810 * \sa MEDFileMesh::removeOrphanFamilies
812 void MEDFileMesh::removeFamiliesReferedByNoGroups()
814 std::map<std::string,int> fams;
815 std::set<std::string> sfams;
816 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
817 sfams.insert((*it).first);
818 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
819 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
821 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
822 if(*it!=DFT_FAM_NAME)
823 _families.erase(*it);
827 * This method has no impact on groups. This method only works on families. This method firstly removes families not referred by any groups in \a this, then all unused entities
828 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
829 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
831 * This method also raises an exception if a family belonging to a group has also id 0 (which is not right in MED file format). You should never encounter this case using addGroup method.
833 * \sa MEDFileMesh::removeOrphanFamilies, MEDFileMesh::zipFamilies
835 void MEDFileMesh::rearrangeFamilies()
837 checkOrphanFamilyZero();
838 removeFamiliesReferedByNoGroups();
840 std::vector<int> levels(getNonEmptyLevelsExt());
841 std::set<int> idsRefed;
842 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
844 idsRefed.insert((*it).second);
847 if(!getGroupsOnFamily((*it).first).empty())
849 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Not orphan family \"" << (*it).first << "\" has id 0 ! This method may alterate groups in this for such a case !";
850 throw INTERP_KERNEL::Exception(oss.str());
854 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
856 const DataArrayInt *fams(0);
859 fams=getFamilyFieldAtLevel(*it);
861 catch(INTERP_KERNEL::Exception& e) { }
864 std::vector<bool> v(fams->getNumberOfTuples(),false);
865 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
866 fams->switchOnTupleEqualTo(*pt,v);
867 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
868 if(!unfetchedIds->empty())
870 MCAuto<DataArrayInt> newFams(fams->deepCopy());
871 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
872 setFamilyFieldArr(*it,newFams);
875 removeOrphanFamilies();
879 * This method has no impact on existing groups. This method has only impact on families behind the groups.
880 * This method is especially useful for MED file structures having used too much families to define their groups and that need to be merged without modification of their groups.
881 * To zip families, firstly this method first removes families refered by no groups (see MEDFileMesh::removeFamiliesReferedByNoGroups), then this method puts together families lying on a same set of groups. If the set of families having same groups has a length higher than 1, the families are merged into a single family
882 * having the name of the first family appearing in family definition and with the corresponding family ID.
884 void MEDFileMesh::zipFamilies()
886 checkOrphanFamilyZero();
887 removeFamiliesReferedByNoGroups();
888 std::map< std::set<std::string> , std::vector<std::string> > setOfFamilies;
889 // firstly, store in setOfFamilies as key the common set of groups, and as value the families having such same set of groups
890 for(auto fam : _families)
892 std::vector<std::string> grps( this->getGroupsOnFamily( fam.first ) );
893 std::set<std::string> sgrps(grps.begin(),grps.end());
894 setOfFamilies[sgrps].push_back(fam.first);
897 std::map<std::string, std::vector<std::string> > newGroups(_groups);
898 std::map<std::string,int> newFams(_families);
899 std::vector<int> levels(getNonEmptyLevelsExt());
900 std::map<int, std::vector<int> > famIdsToSubstitute;
901 // iterate on all different set of groups
902 std::set<std::string> familiesToKill;
903 for(auto setOfCommonGrp : setOfFamilies)
905 if( setOfCommonGrp.second.size()<=1 )
907 for(auto fam=setOfCommonGrp.second.begin()+1 ; fam != setOfCommonGrp.second.end() ; fam++)
908 familiesToKill.insert(*fam);
910 // iterate on all different set of groups
911 for(auto setOfCommonGrp : setOfFamilies)
913 if( setOfCommonGrp.second.size()<=1 )
915 std::string newFamName(setOfCommonGrp.second[0]);
916 auto newFamID(_families[newFamName]);
917 for(auto grpToBeModified : setOfCommonGrp.first)
919 std::vector<std::string> newFamiliesForCurGrp(1,newFamName);
920 const std::vector<std::string>& familiesOnCurGrp(_groups[grpToBeModified]);
921 const std::vector<std::string>& familiesToZip(setOfCommonGrp.second);
922 std::for_each(familiesToZip.begin(),familiesToZip.end(),[&famIdsToSubstitute,this,newFamID](const std::string& elt) { famIdsToSubstitute[newFamID].push_back(this->getFamilyId(elt)); });
923 // for each family shared by the current group only keep those not sharing setOfCommonGrp.second
924 std::for_each(familiesOnCurGrp.begin(),familiesOnCurGrp.end(),[&familiesToKill,&newFamiliesForCurGrp](const std::string& elt)
925 { if( familiesToKill.find(elt) == familiesToKill.end() ) { newFamiliesForCurGrp.push_back(elt); } });
926 newGroups[grpToBeModified] = newFamiliesForCurGrp;
928 for(auto familyToKill = setOfCommonGrp.second.begin()+1 ; familyToKill != setOfCommonGrp.second.end(); ++familyToKill)
930 newFams.erase( newFams.find(*familyToKill) );
934 // apply modifications in datastructure
935 for(auto famIdsSubstSession : famIdsToSubstitute)
937 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
939 DataArrayInt *fams(nullptr);
942 fams=getFamilyFieldAtLevel(*it);
944 catch(INTERP_KERNEL::Exception& e) { }
947 MCAuto<DataArrayInt> idsToModif(fams->findIdsEqualList(famIdsSubstSession.second.data(),famIdsSubstSession.second.data()+famIdsSubstSession.second.size()));
948 fams->setPartOfValuesSimple3(famIdsSubstSession.first,idsToModif->begin(),idsToModif->end(),0,1,1);
956 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
958 void MEDFileMesh::checkOrphanFamilyZero() const
960 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
962 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
964 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
965 throw INTERP_KERNEL::Exception(oss.str().c_str());
971 * Renames a group in \a this mesh.
972 * \param [in] oldName - a current name of the group to rename.
973 * \param [in] newName - a new group name.
974 * \throw If no group named \a oldName exists in \a this mesh.
975 * \throw If a group named \a newName already exists.
977 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
979 std::string oname(oldName);
980 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
981 std::vector<std::string> grps=getGroupsNames();
982 if(it==_groups.end())
984 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
985 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
986 throw INTERP_KERNEL::Exception(oss.str().c_str());
988 std::string nname(newName);
989 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
990 if(it2!=_groups.end())
992 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
993 throw INTERP_KERNEL::Exception(oss.str().c_str());
995 std::vector<std::string> cpy=(*it).second;
997 _groups[newName]=cpy;
1001 * Changes an id of a family in \a this mesh.
1002 * This method calls changeFamilyIdArr().
1003 * \param [in] oldId - a current id of the family.
1004 * \param [in] newId - a new family id.
1006 void MEDFileMesh::changeFamilyId(int oldId, int newId)
1008 changeFamilyIdArr(oldId,newId);
1009 std::map<std::string,int> fam2;
1010 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1012 if((*it).second==oldId)
1013 fam2[(*it).first]=newId;
1015 fam2[(*it).first]=(*it).second;
1021 * Renames a family in \a this mesh.
1022 * \param [in] oldName - a current name of the family to rename.
1023 * \param [in] newName - a new family name.
1024 * \throw If no family named \a oldName exists in \a this mesh.
1025 * \throw If a family named \a newName already exists.
1027 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
1029 std::string oname(oldName);
1030 std::map<std::string, int >::iterator it=_families.find(oname);
1031 std::vector<std::string> fams=getFamiliesNames();
1032 if(it==_families.end())
1034 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
1035 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1036 throw INTERP_KERNEL::Exception(oss.str().c_str());
1038 std::string nname(newName);
1039 std::map<std::string, int >::iterator it2=_families.find(nname);
1040 if(it2!=_families.end())
1042 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
1043 throw INTERP_KERNEL::Exception(oss.str().c_str());
1045 int cpy=(*it).second;
1046 _families.erase(it);
1047 _families[newName]=cpy;
1048 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
1050 std::vector<std::string>& v=(*it3).second;
1051 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
1058 * Checks if \a this and another mesh contains the same families.
1059 * \param [in] other - the mesh to compare with \a this one.
1060 * \param [in,out] what - an unused parameter.
1061 * \return bool - \c true if number of families and their ids are the same in the two
1062 * meshes. Families with the id == \c 0 are not considered.
1064 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
1066 if(_families==other->_families)
1068 std::map<std::string,int> fam0;
1069 std::map<std::string,int> fam1;
1070 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1072 fam0[(*it).first]=(*it).second;
1073 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
1075 fam1[(*it).first]=(*it).second;
1080 * Checks if \a this and another mesh contains the same groups.
1081 * \param [in] other - the mesh to compare with \a this one.
1082 * \param [in,out] what - a string describing a difference of groups of the two meshes
1083 * in case if this method returns \c false.
1084 * \return bool - \c true if number of groups and families constituting them are the
1085 * same in the two meshes.
1087 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
1089 if(_groups==other->_groups)
1092 std::size_t sz=_groups.size();
1093 if(sz!=other->_groups.size())
1095 what="Groups differ because not same number !\n";
1100 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
1101 for(std::size_t i=0;i<sz && ret;i++,it1++)
1103 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
1104 if(it2!=other->_groups.end())
1106 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
1107 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1113 what="A group in first mesh exists not in other !\n";
1119 std::ostringstream oss; oss << "Groups description differs :\n";
1120 oss << "First group description :\n";
1121 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1123 oss << " Group \"" << (*it).first << "\" on following families :\n";
1124 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1125 oss << " \"" << *it2 << "\n";
1127 oss << "Second group description :\n";
1128 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1130 oss << " Group \"" << (*it).first << "\" on following families :\n";
1131 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1132 oss << " \"" << *it2 << "\n";
1140 * Checks if a group with a given name exists in \a this mesh.
1141 * \param [in] groupName - the group name.
1142 * \return bool - \c true the group \a groupName exists in \a this mesh.
1144 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1146 std::string grpName(groupName);
1147 return _groups.find(grpName)!=_groups.end();
1151 * Checks if a family with a given id exists in \a this mesh.
1152 * \param [in] famId - the family id.
1153 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1155 bool MEDFileMesh::existsFamily(int famId) const
1157 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1158 if((*it2).second==famId)
1164 * Checks if a family with a given name exists in \a this mesh.
1165 * \param [in] familyName - the family name.
1166 * \return bool - \c true the family \a familyName exists in \a this mesh.
1168 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1170 std::string fname(familyName);
1171 return _families.find(fname)!=_families.end();
1175 * Sets an id of a family.
1176 * \param [in] familyName - the family name.
1177 * \param [in] id - a new id of the family.
1179 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1181 std::string fname(familyName);
1182 _families[fname]=id;
1185 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1187 std::string fname(familyName);
1188 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1189 if((*it).second==id)
1191 if((*it).first!=familyName)
1193 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1194 throw INTERP_KERNEL::Exception(oss.str().c_str());
1197 _families[fname]=id;
1201 * Adds a family to \a this mesh.
1202 * \param [in] familyName - a name of the family.
1203 * \param [in] famId - an id of the family.
1204 * \throw If a family with the same name or id already exists in \a this mesh.
1206 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1208 std::string fname(familyName);
1209 std::map<std::string,int>::const_iterator it=_families.find(fname);
1210 if(it==_families.end())
1212 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1213 if((*it2).second==famId)
1215 std::ostringstream oss;
1216 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1217 throw INTERP_KERNEL::Exception(oss.str().c_str());
1219 _families[fname]=famId;
1223 if((*it).second!=famId)
1225 std::ostringstream oss;
1226 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1227 throw INTERP_KERNEL::Exception(oss.str().c_str());
1233 * Creates a group including all mesh entities of given dimension.
1234 * \warning This method does \b not guarantee that the created group includes mesh
1235 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1236 * present in family fields of different dimensions. To assure this, call
1237 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1238 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1240 * \param [in] groupName - a name of the new group.
1241 * \throw If a group named \a groupName already exists.
1242 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1243 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1245 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1247 std::string grpName(groupName);
1248 std::vector<int> levs=getNonEmptyLevelsExt();
1249 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1251 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1252 oss << "Available relative ext levels are : ";
1253 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1254 throw INTERP_KERNEL::Exception(oss.str().c_str());
1256 if(existsGroup(groupName))
1258 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1259 oss << "Already existing groups are : ";
1260 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1261 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1262 throw INTERP_KERNEL::Exception(oss.str().c_str());
1264 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1266 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1267 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1268 std::vector<std::string> familiesOnWholeGroup;
1269 for(const int *it=famIds->begin();it!=famIds->end();it++)
1272 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1274 _groups[grpName]=familiesOnWholeGroup;
1278 * Ensures that given family ids do not present in family fields of dimensions different
1279 * than given ones. If a family id is present in the family fields of dimensions different
1280 * than the given ones, a new family is created and the whole data is updated accordingly.
1281 * \param [in] famIds - a sequence of family ids to check.
1282 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1283 * famIds should exclusively belong.
1284 * \return bool - \c true if no modification is done in \a this mesh by this method.
1286 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1288 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1289 std::vector<int> levs=getNonEmptyLevelsExt();
1290 std::set<int> levs2(levs.begin(),levs.end());
1291 std::vector<int> levsToTest;
1292 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1293 std::set<int> famIds2(famIds.begin(),famIds.end());
1296 if(!_families.empty())
1297 maxFamId=getMaxFamilyId()+1;
1298 std::vector<std::string> allFams=getFamiliesNames();
1299 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1301 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1304 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1305 std::vector<int> tmp;
1306 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1307 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1310 std::string famName=getFamilyNameGivenId(*it2);
1311 std::ostringstream oss; oss << "Family_" << maxFamId;
1312 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1313 addFamilyOnAllGroupsHaving(famName,zeName);
1314 _families[zeName]=maxFamId;
1315 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1324 * Adds a family to a given group in \a this mesh. If the group with a given name does
1325 * not exist, it is created.
1326 * \param [in] grpName - the name of the group to add the family in.
1327 * \param [in] famName - the name of the family to add to the group named \a grpName.
1328 * \throw If \a grpName or \a famName is an empty string.
1329 * \throw If no family named \a famName is present in \a this mesh.
1331 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1333 std::string grpn(grpName);
1334 std::string famn(famName);
1335 if(grpn.empty() || famn.empty())
1336 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1337 std::vector<std::string> fams=getFamiliesNames();
1338 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1340 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1341 oss << "Create this family or choose an existing one ! Existing fams are : ";
1342 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1343 throw INTERP_KERNEL::Exception(oss.str().c_str());
1345 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1346 if(it==_groups.end())
1348 _groups[grpn].push_back(famn);
1352 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1353 if(it2==(*it).second.end())
1354 (*it).second.push_back(famn);
1359 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1360 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1361 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1363 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1365 std::string famNameCpp(famName);
1366 std::string otherCpp(otherFamName);
1367 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1369 std::vector<std::string>& v=(*it).second;
1370 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1372 v.push_back(otherCpp);
1377 void MEDFileMesh::checkNoGroupClash(const DataArrayInt *famArr, const std::string& grpName) const
1379 std::vector<std::string> grpsNames(getGroupsNames());
1380 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
1382 std::vector<int> famIds(getFamiliesIdsOnGroup(grpName));
1383 if(famArr->presenceOfValue(famIds))
1385 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
1386 throw INTERP_KERNEL::Exception(oss.str().c_str());
1391 * \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).
1392 * \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)
1394 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1397 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1398 std::string grpName(ids->getName());
1400 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1401 ids->checkStrictlyMonotonic(true);
1402 checkNoGroupClash(famArr,grpName);
1403 MCAuto<DataArrayInt> famArrTmp; famArrTmp.takeRef(famArr);
1404 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1405 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1406 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1407 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1408 std::vector<int> familyIds;
1409 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1410 int maxVal=getTheMaxAbsFamilyId()+1;
1411 std::map<std::string,int> families(_families);
1412 std::map<std::string, std::vector<std::string> > groups(_groups);
1413 std::vector<std::string> fams;
1414 bool created(false);
1415 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1417 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1418 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1419 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1420 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1423 bool isFamPresent=false;
1424 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1425 isFamPresent=(*itl)->presenceOfValue(*famId);
1426 if(!isFamPresent && *famId!=0)
1427 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1430 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1431 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1432 fams.push_back(locFamName);
1433 if(existsFamily(*famId))
1435 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1436 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1439 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1443 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1444 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1445 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1446 if(existsFamily(*famId))
1448 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1449 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1454 for(std::size_t i=0;i<familyIds.size();i++)
1456 DataArrayInt *da=idsPerfamiliyIds[i];
1457 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1460 std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
1461 if(itt!=groups.end())
1463 std::vector<std::string>& famsOnGrp((*itt).second);
1464 famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
1467 groups[grpName]=fams;
1471 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1473 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1476 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1478 std::string fam(familyNameToChange);
1479 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1481 std::vector<std::string>& fams((*it).second);
1482 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1486 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1492 * Returns a name of the family having a given id or, if no such a family exists, creates
1493 * a new uniquely named family and returns its name.
1494 * \param [in] id - the id of the family whose name is required.
1495 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1496 * \return std::string - the name of the existing or the created family.
1497 * \throw If it is not possible to create a unique family name.
1499 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1501 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1505 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1506 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1507 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1508 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1510 * This method will throws an exception if it is not possible to create a unique family name.
1512 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1514 std::vector<std::string> famAlreadyExisting(families.size());
1516 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1518 if((*it).second!=id)
1520 famAlreadyExisting[ii]=(*it).first;
1529 std::ostringstream oss; oss << "Family_" << id;
1530 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1536 * Sets names and ids of all families in \a this mesh.
1537 * \param [in] info - a map of a family name to a family id.
1539 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1545 * Sets names of all groups and families constituting them in \a this mesh.
1546 * \param [in] info - a map of a group name to a vector of names of families
1547 * constituting the group.
1549 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1555 * Returns an id of the family having a given name.
1556 * \param [in] name - the name of the family of interest.
1557 * \return int - the id of the family of interest.
1558 * \throw If no family with such a \a name exists.
1560 int MEDFileMesh::getFamilyId(const std::string& name) const
1562 std::map<std::string, int>::const_iterator it=_families.find(name);
1563 if(it==_families.end())
1565 std::vector<std::string> fams(getFamiliesNames());
1566 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1567 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1568 throw INTERP_KERNEL::Exception(oss.str().c_str());
1570 return (*it).second;
1574 * Returns ids of the families having given names.
1575 * \param [in] fams - a sequence of the names of families of interest.
1576 * \return std::vector<int> - a sequence of the ids of families of interest.
1577 * \throw If \a fams contains a name of an inexistent family.
1579 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1581 std::vector<int> ret(fams.size());
1583 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1585 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1586 if(it2==_families.end())
1588 std::vector<std::string> fams2=getFamiliesNames();
1589 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1590 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1591 throw INTERP_KERNEL::Exception(oss.str().c_str());
1593 ret[i]=(*it2).second;
1599 * Returns a maximal abs(id) of families in \a this mesh.
1600 * \return int - the maximal norm of family id.
1601 * \throw If there are no families in \a this mesh.
1603 int MEDFileMesh::getMaxAbsFamilyId() const
1605 if(_families.empty())
1606 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1607 int ret=-std::numeric_limits<int>::max();
1608 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1610 ret=std::max(std::abs((*it).second),ret);
1616 * Returns a maximal id of families in \a this mesh.
1617 * \return int - the maximal family id.
1618 * \throw If there are no families in \a this mesh.
1620 int MEDFileMesh::getMaxFamilyId() const
1622 if(_families.empty())
1623 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1624 int ret=-std::numeric_limits<int>::max();
1625 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1627 ret=std::max((*it).second,ret);
1633 * Returns a minimal id of families in \a this mesh.
1634 * \return int - the minimal family id.
1635 * \throw If there are no families in \a this mesh.
1637 int MEDFileMesh::getMinFamilyId() const
1639 if(_families.empty())
1640 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1641 int ret=std::numeric_limits<int>::max();
1642 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1644 ret=std::min((*it).second,ret);
1650 * Returns a maximal id of families in \a this mesh. Not only named families are
1651 * considered but all family fields as well.
1652 * \return int - the maximal family id.
1654 int MEDFileMesh::getTheMaxAbsFamilyId() const
1656 int m1=-std::numeric_limits<int>::max();
1657 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1658 m1=std::max(std::abs((*it).second),m1);
1659 int m2=getMaxAbsFamilyIdInArrays();
1660 return std::max(m1,m2);
1664 * Returns a maximal id of families in \a this mesh. Not only named families are
1665 * considered but all family fields as well.
1666 * \return int - the maximal family id.
1668 int MEDFileMesh::getTheMaxFamilyId() const
1670 int m1=-std::numeric_limits<int>::max();
1671 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1672 m1=std::max((*it).second,m1);
1673 int m2=getMaxFamilyIdInArrays();
1674 return std::max(m1,m2);
1678 * Returns a minimal id of families in \a this mesh. Not only named families are
1679 * considered but all family fields as well.
1680 * \return int - the minimal family id.
1682 int MEDFileMesh::getTheMinFamilyId() const
1684 int m1=std::numeric_limits<int>::max();
1685 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1686 m1=std::min((*it).second,m1);
1687 int m2=getMinFamilyIdInArrays();
1688 return std::min(m1,m2);
1692 * This method only considers the maps. The contain of family array is ignored here.
1694 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1696 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1698 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1700 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1701 v.insert((*it).second);
1702 ret->alloc((int)v.size(),1);
1703 std::copy(v.begin(),v.end(),ret->getPointer());
1708 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1710 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1712 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1714 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1715 MCAuto<DataArrayInt> ret;
1716 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1718 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1719 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1720 if((DataArrayInt *) ret)
1721 ret=dv->buildUnion(ret);
1729 * true is returned if no modification has been needed. false if family
1730 * renumbering has been needed.
1732 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1734 std::vector<int> levs=getNonEmptyLevelsExt();
1735 std::set<int> allFamIds;
1736 int maxId=getMaxFamilyId()+1;
1737 std::map<int,std::vector<int> > famIdsToRenum;
1738 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1740 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1743 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1745 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1747 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1749 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1752 if(famIdsToRenum.empty())
1754 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1755 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1757 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1758 int *famIdsToChange=fam->getPointer();
1759 std::map<int,int> ren;
1760 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1762 if(allIds->presenceOfValue(*it3))
1764 std::string famName=getFamilyNameGivenId(*it3);
1765 std::vector<std::string> grps=getGroupsOnFamily(famName);
1768 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1769 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1770 addFamilyOnGrp((*it4),newFam);
1773 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1774 for(const int *id=ids->begin();id!=ids->end();id++)
1775 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1781 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1782 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1783 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1784 * This method will throw an exception if a same family id is detected in different level.
1785 * \warning This policy is the opposite of those in MED file documentation ...
1787 void MEDFileMesh::normalizeFamIdsTrio()
1789 ensureDifferentFamIdsPerLevel();
1790 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1791 std::vector<int> levs=getNonEmptyLevelsExt();
1792 std::set<int> levsS(levs.begin(),levs.end());
1793 std::set<std::string> famsFetched;
1794 std::map<std::string,int> families;
1795 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1798 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1802 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1803 std::map<int,int> ren;
1804 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1806 int nbOfTuples=fam->getNumberOfTuples();
1807 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1808 for(int *w=start;w!=start+nbOfTuples;w++)
1810 for(const int *it=tmp->begin();it!=tmp->end();it++)
1812 if(allIds->presenceOfValue(*it))
1814 std::string famName=getFamilyNameGivenId(*it);
1815 families[famName]=ren[*it];
1816 famsFetched.insert(famName);
1821 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1824 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1828 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1829 std::map<int,int> ren;
1830 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1832 int nbOfTuples=fam->getNumberOfTuples();
1833 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1834 for(int *w=start;w!=start+nbOfTuples;w++)
1836 for(const int *it=tmp->begin();it!=tmp->end();it++)
1838 if(allIds->presenceOfValue(*it))
1840 std::string famName=getFamilyNameGivenId(*it);
1841 families[famName]=ren[*it];
1842 famsFetched.insert(famName);
1847 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1849 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1852 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1853 fam->fillWithZero();
1854 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1855 if(allIds->presenceOfValue(*it3))
1857 std::string famName=getFamilyNameGivenId(*it3);
1858 families[famName]=0;
1859 famsFetched.insert(famName);
1864 std::vector<std::string> allFams=getFamiliesNames();
1865 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1866 std::set<std::string> unFetchedIds;
1867 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1868 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1869 families[*it4]=_families[*it4];
1874 * This method normalizes fam id with the following policy.
1875 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1876 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1877 * This method will throw an exception if a same family id is detected in different level.
1879 void MEDFileMesh::normalizeFamIdsMEDFile()
1881 ensureDifferentFamIdsPerLevel();
1882 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1883 std::vector<int> levs=getNonEmptyLevelsExt();
1884 std::set<int> levsS(levs.begin(),levs.end());
1885 std::set<std::string> famsFetched;
1886 std::map<std::string,int> families;
1888 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1891 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1894 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1895 std::map<int,int> ren;
1896 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1898 int nbOfTuples=fam->getNumberOfTuples();
1899 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1900 for(int *w=start;w!=start+nbOfTuples;w++)
1902 for(const int *it=tmp->begin();it!=tmp->end();it++)
1904 if(allIds->presenceOfValue(*it))
1906 std::string famName=getFamilyNameGivenId(*it);
1907 families[famName]=ren[*it];
1908 famsFetched.insert(famName);
1914 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1916 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1919 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1920 std::map<int,int> ren;
1921 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1923 int nbOfTuples=fam->getNumberOfTuples();
1924 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1925 for(int *w=start;w!=start+nbOfTuples;w++)
1927 for(const int *it=tmp->begin();it!=tmp->end();it++)
1929 if(allIds->presenceOfValue(*it))
1931 std::string famName=getFamilyNameGivenId(*it);
1932 families[famName]=ren[*it];
1933 famsFetched.insert(famName);
1939 std::vector<std::string> allFams=getFamiliesNames();
1940 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1941 std::set<std::string> unFetchedIds;
1942 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1943 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1944 families[*it4]=_families[*it4];
1949 * Returns a name of the family by its id. If there are several families having the given
1950 * id, the name first in lexical order is returned.
1951 * \param [in] id - the id of the family whose name is required.
1952 * \return std::string - the name of the found family.
1953 * \throw If no family with the given \a id exists.
1955 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1957 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1958 if((*it).second==id)
1960 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1961 throw INTERP_KERNEL::Exception(oss.str().c_str());
1965 * Returns a string describing \a this mesh. This description includes the mesh name and
1966 * the mesh description string.
1967 * \return std::string - the mesh information string.
1969 std::string MEDFileMesh::simpleRepr() const
1971 std::ostringstream oss;
1972 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1973 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1974 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1979 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1980 * an empty one is created.
1982 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1984 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1987 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1988 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1989 arr->fillWithZero();
1990 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1991 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1995 * Returns ids of mesh entities contained in a given group of a given dimension.
1996 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1998 * \param [in] grp - the name of the group of interest.
1999 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2000 * returned instead of ids.
2001 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2002 * numbers, if available and required, of mesh entities of the group. The caller
2003 * is to delete this array using decrRef() as it is no more needed.
2004 * \throw If the name of a nonexistent group is specified.
2005 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2007 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2009 std::vector<std::string> tmp(1);
2011 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
2017 * Returns ids of mesh entities contained in given groups of a given dimension.
2018 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2020 * \param [in] grps - the names of the groups of interest.
2021 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2022 * returned instead of ids.
2023 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2024 * numbers, if available and required, of mesh entities of the groups. The caller
2025 * is to delete this array using decrRef() as it is no more needed.
2026 * \throw If the name of a nonexistent group is present in \a grps.
2027 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2029 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2031 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2032 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
2036 * Returns ids of mesh entities contained in a given family of a given dimension.
2037 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2039 * \param [in] fam - the name of the family of interest.
2040 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2041 * returned instead of ids.
2042 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2043 * numbers, if available and required, of mesh entities of the family. The caller
2044 * is to delete this array using decrRef() as it is no more needed.
2045 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2047 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2049 std::vector<std::string> tmp(1);
2051 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
2057 * Returns ids of nodes contained in a given group.
2058 * \param [in] grp - the name of the group of interest.
2059 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2060 * returned instead of ids.
2061 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2062 * numbers, if available and required, of nodes of the group. The caller
2063 * is to delete this array using decrRef() as it is no more needed.
2064 * \throw If the name of a nonexistent group is specified.
2065 * \throw If the family field is missing for nodes.
2067 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
2069 std::vector<std::string> tmp(1);
2071 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
2077 * Returns ids of nodes contained in given groups.
2078 * \param [in] grps - the names of the groups of interest.
2079 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2080 * returned instead of ids.
2081 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2082 * numbers, if available and required, of nodes of the groups. The caller
2083 * is to delete this array using decrRef() as it is no more needed.
2084 * \throw If the name of a nonexistent group is present in \a grps.
2085 * \throw If the family field is missing for nodes.
2087 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
2089 return getGroupsArr(1,grps,renum);
2093 * Returns ids of nodes contained in a given group.
2094 * \param [in] grp - the name of the group of interest.
2095 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2096 * returned instead of ids.
2097 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2098 * numbers, if available and required, of nodes of the group. The caller
2099 * is to delete this array using decrRef() as it is no more needed.
2100 * \throw If the name of a nonexistent group is specified.
2101 * \throw If the family field is missing for nodes.
2103 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
2105 std::vector<std::string> tmp(1);
2107 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
2113 * Returns ids of nodes contained in given families.
2114 * \param [in] fams - the names of the families of interest.
2115 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2116 * returned instead of ids.
2117 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2118 * numbers, if available and required, of nodes of the families. The caller
2119 * is to delete this array using decrRef() as it is no more needed.
2120 * \throw If the family field is missing for nodes.
2122 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2124 return getFamiliesArr(1,fams,renum);
2128 * Adds groups of given dimension and creates corresponding families and family fields
2129 * given ids of mesh entities of each group.
2130 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2131 * \param [in] grps - a sequence of arrays of ids each describing a group.
2132 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2134 * \throw If names of some groups in \a grps are equal.
2135 * \throw If \a grps includes a group with an empty name.
2136 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2137 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2139 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2143 std::set<std::string> grpsName;
2144 std::vector<std::string> grpsName2(grps.size());
2147 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2149 grpsName.insert((*it)->getName());
2150 grpsName2[i]=(*it)->getName();
2152 if(grpsName.size()!=grps.size())
2153 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2154 if(grpsName.find(std::string(""))!=grpsName.end())
2155 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2156 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2157 MCAuto<DataArrayInt> fam;
2158 std::vector< std::vector<int> > fidsOfGroups;
2161 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2165 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2166 for(unsigned int ii=0;ii<grps.size();ii++)
2168 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2169 grps2[ii]->setName(grps[ii]->getName());
2171 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2172 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2175 if(!_families.empty())
2176 offset=getMaxAbsFamilyId()+1;
2177 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2178 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2179 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2180 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2184 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2185 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2186 * For the moment, the two last input parameters are not taken into account.
2188 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2190 std::map<int,std::string> famInv;
2191 for(const int *it=famIds->begin();it!=famIds->end();it++)
2193 std::ostringstream oss;
2194 oss << "Family_" << (*it);
2195 _families[oss.str()]=(*it);
2196 famInv[*it]=oss.str();
2199 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2201 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2203 _groups[grpNames[i]].push_back(famInv[*it2]);
2208 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2210 std::vector<int> levs(getNonEmptyLevels());
2211 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2212 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2214 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2215 ret.insert(ret.end(),elts.begin(),elts.end());
2221 * \sa getAllDistributionOfTypes
2223 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2225 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2226 return mLev->getDistributionOfTypes();
2229 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2231 loadLL(fid,mName,dt,it,mrs);
2232 loadJointsFromFile(fid);
2233 loadEquivalences(fid);
2236 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2238 famArr->applyLin(offset>0?1:-1,offset,0);
2239 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2242 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2243 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2248 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2249 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2250 * If this method fails to find such a name it will throw an exception.
2252 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2255 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2258 std::size_t len=nameTry.length();
2259 for(std::size_t ii=1;ii<len;ii++)
2261 std::string tmp=nameTry.substr(ii,len-ii);
2262 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2268 for(std::size_t i=1;i<30;i++)
2270 std::string tmp1(nameTry.at(0),i);
2272 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2278 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2280 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2282 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2285 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2287 std::size_t nbOfChunks=code.size()/3;
2288 if(code.size()%3!=0)
2289 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2291 for(std::size_t i=0;i<nbOfChunks;i++)
2300 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2301 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2302 * If _name is not empty and that 'm' has the same name nothing is done.
2303 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2305 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2308 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2313 std::string name(m->getName());
2318 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2319 oss << name << "' ! Names must match !";
2320 throw INTERP_KERNEL::Exception(oss.str().c_str());
2324 if(_desc_name.empty())
2325 _desc_name=m->getDescription();
2328 std::string name(m->getDescription());
2331 if(_desc_name!=name)
2333 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2334 oss << name << "' ! Names must match !";
2335 throw INTERP_KERNEL::Exception(oss.str().c_str());
2341 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2343 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2344 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2346 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2347 oss << " - Groups lying on this family : ";
2348 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2349 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2350 oss << std::endl << std::endl;
2355 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2356 * file. The mesh to load is specified by its name and numbers of a time step and an
2358 * \param [in] fileName - the name of MED file to read.
2359 * \param [in] mName - the name of the mesh to read.
2360 * \param [in] dt - the number of a time step.
2361 * \param [in] it - the number of an iteration.
2362 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2363 * mesh using decrRef() as it is no more needed.
2364 * \throw If the file is not readable.
2365 * \throw If there is no mesh with given attributes in the file.
2366 * \throw If the mesh in the file is not an unstructured one.
2368 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2370 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2371 return New(fid,mName,dt,it,mrs);
2374 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2376 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2380 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2381 * file. The first mesh in the file is loaded.
2382 * \param [in] fileName - the name of MED file to read.
2383 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2384 * mesh using decrRef() as it is no more needed.
2385 * \throw If the file is not readable.
2386 * \throw If there is no meshes in the file.
2387 * \throw If the mesh in the file is not an unstructured one.
2389 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2391 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2392 return New(fid,mrs);
2396 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2398 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2401 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2402 throw INTERP_KERNEL::Exception(oss.str().c_str());
2405 MEDCoupling::MEDCouplingMeshType meshType;
2407 MEDCoupling::MEDCouplingAxisType dummy3;
2408 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2409 return T::New(fid,ms.front(),dt,it,mrs);
2412 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2414 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2418 * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2419 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2421 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2424 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2425 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2426 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2427 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2429 m2D->setCoords(m3D->getCoords());
2430 ret->setMeshAtLevel(0,m3D);
2431 ret->setMeshAtLevel(-1,m2D);
2432 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2437 * Returns an empty instance of MEDFileUMesh.
2438 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2439 * mesh using decrRef() as it is no more needed.
2441 MEDFileUMesh *MEDFileUMesh::New()
2443 return new MEDFileUMesh;
2447 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2448 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2449 * \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.
2450 * 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
2451 * at most the memory consumtion.
2453 * \param [in] fileName - the name of the file.
2454 * \param [in] mName - the name of the mesh to be read.
2455 * \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.
2456 * \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.
2457 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2458 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2459 * \param [in] mrs - the request for what to be loaded.
2460 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2462 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)
2464 MEDFileUtilities::CheckFileForRead(fileName);
2465 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2466 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2470 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2471 * This method is \b NOT wrapped into python.
2473 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)
2475 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2476 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2480 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2482 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2483 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2487 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2489 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2490 ret.push_back((const DataArrayDouble*)_coords);
2491 ret.push_back((const DataArrayInt *)_fam_coords);
2492 ret.push_back((const DataArrayInt *)_num_coords);
2493 ret.push_back((const DataArrayInt *)_global_num_coords);
2494 ret.push_back((const DataArrayInt *)_rev_num_coords);
2495 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2496 ret.push_back((const PartDefinition *)_part_coords);
2497 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2498 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2499 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2500 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2504 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2506 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2510 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2512 return new MEDFileUMesh;
2515 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2517 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2518 ret->deepCpyEquivalences(*this);
2519 if(_coords.isNotNull())
2520 ret->_coords=_coords->deepCopy();
2521 if(_fam_coords.isNotNull())
2522 ret->_fam_coords=_fam_coords->deepCopy();
2523 if(_num_coords.isNotNull())
2524 ret->_num_coords=_num_coords->deepCopy();
2525 if(_global_num_coords.isNotNull())
2526 ret->_global_num_coords=_global_num_coords->deepCopy();
2527 if(_rev_num_coords.isNotNull())
2528 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2529 if(_name_coords.isNotNull())
2530 ret->_name_coords=_name_coords->deepCopy();
2532 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2534 if((const MEDFileUMeshSplitL1 *)(*it))
2535 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2537 if((const PartDefinition*)_part_coords)
2538 ret->_part_coords=_part_coords->deepCopy();
2543 * Checks if \a this and another mesh are equal.
2544 * \param [in] other - the mesh to compare with.
2545 * \param [in] eps - a precision used to compare real values.
2546 * \param [in,out] what - the string returning description of unequal data.
2547 * \return bool - \c true if the meshes are equal, \c false, else.
2549 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2551 if(!MEDFileMesh::isEqual(other,eps,what))
2553 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2556 what="Mesh types differ ! This is unstructured and other is NOT !";
2559 clearNonDiscrAttributes();
2560 otherC->clearNonDiscrAttributes();
2561 const DataArrayDouble *coo1=_coords;
2562 const DataArrayDouble *coo2=otherC->_coords;
2563 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2565 what="Mismatch of coordinates ! One is defined and not other !";
2570 bool ret=coo1->isEqual(*coo2,eps);
2573 what="Coords differ !";
2578 const DataArrayInt *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2579 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2581 what="Mismatch of families arr on nodes ! One is defined and not other !";
2586 bool ret=famc1->isEqual(*famc2);
2589 what="Families arr on node differ !";
2595 const DataArrayInt *numc1(_num_coords),*numc2(otherC->_num_coords);
2596 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2598 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2603 bool ret=numc1->isEqual(*numc2);
2606 what="Numbering arr on node differ !";
2612 const DataArrayInt *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2613 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2615 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2620 bool ret=gnumc1->isEqual(*gnumc2);
2623 what="Global numbering arr on node differ !";
2629 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2630 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2632 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2637 bool ret=namec1->isEqual(*namec2);
2640 what="Names arr on node differ !";
2645 if(_ms.size()!=otherC->_ms.size())
2647 what="Number of levels differs !";
2650 std::size_t sz=_ms.size();
2651 for(std::size_t i=0;i<sz;i++)
2653 const MEDFileUMeshSplitL1 *s1=_ms[i];
2654 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2655 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2657 what="Mismatch of presence of sub levels !";
2662 bool ret=s1->isEqual(s2,eps,what);
2667 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2670 if((!pd0 && pd1) || (pd0 && !pd1))
2672 what=std::string("node part def is defined only for one among this or other !");
2675 return pd0->isEqual(pd1,what);
2679 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2680 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2681 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2682 * \throw if internal family array is inconsistent
2683 * \sa checkSMESHConsistency()
2685 void MEDFileUMesh::checkConsistency() const
2687 if(!_coords || !_coords->isAllocated())
2690 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2692 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2693 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2694 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2698 int nbCoo = _coords->getNumberOfTuples();
2699 if (_fam_coords.isNotNull())
2700 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2701 if (_num_coords.isNotNull())
2703 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2705 int maxValue=_num_coords->getMaxValue(pos);
2706 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2707 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2709 if (_global_num_coords.isNotNull())
2711 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2713 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2714 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2715 if (_num_coords && !_num_coords->hasUniqueValues())
2716 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2718 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2719 // Now sub part check:
2720 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2721 it != _ms.end(); it++)
2722 (*it)->checkConsistency();
2727 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2728 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2729 * entities as it likes), or non overlapping between all sub-levels.
2730 * \throw if the condition above is not respected
2732 void MEDFileUMesh::checkSMESHConsistency() const
2735 // For all sub-levels, numbering is either always null or with void intersection:
2738 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2739 std::vector< const DataArrayInt * > v;
2740 bool voidOrNot = ((*it)->_num == 0);
2741 for (it++; it != _ms.end(); it++)
2742 if( ((*it)->_num == 0) != voidOrNot )
2743 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2744 else if (!voidOrNot)
2745 v.push_back((*it)->_num);
2748 // don't forget the 1st one:
2749 v.push_back(_ms[0]->_num);
2750 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2751 if (inter->getNumberOfTuples())
2752 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2758 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2759 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2761 void MEDFileUMesh::clearNodeAndCellNumbers()
2763 _num_coords.nullify();
2764 _rev_num_coords.nullify();
2765 _global_num_coords.nullify();
2766 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2768 (*it)->_num.nullify();
2769 (*it)->_rev_num.nullify();
2770 (*it)->_global_num.nullify();
2775 * Clears redundant attributes of incorporated data arrays.
2777 void MEDFileUMesh::clearNonDiscrAttributes() const
2779 MEDFileMesh::clearNonDiscrAttributes();
2780 if(_coords.isNotNull())
2781 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2782 if(_fam_coords.isNotNull())
2783 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2784 if(_num_coords.isNotNull())
2785 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2786 if(_name_coords.isNotNull())
2787 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2788 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2790 if((*it).isNotNull())
2791 (*it)->clearNonDiscrAttributes();
2795 void MEDFileUMesh::setName(const std::string& name)
2797 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2798 if((*it).isNotNull())
2799 (*it)->setName(name);
2800 MEDFileMesh::setName(name);
2803 MEDFileUMesh::MEDFileUMesh()
2807 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2810 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2812 catch(INTERP_KERNEL::Exception& e)
2818 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2819 * See MEDFileUMesh::LoadPartOf for detailed description.
2823 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)
2825 MEDFileUMeshL2 loaderl2;
2826 MEDCoupling::MEDCouplingMeshType meshType;
2829 MEDCoupling::MEDCouplingAxisType dummy3;
2830 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2831 if(meshType!=UNSTRUCTURED)
2833 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2834 throw INTERP_KERNEL::Exception(oss.str().c_str());
2836 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2837 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2841 * \brief Write joints in a file
2843 void MEDFileMesh::writeJoints(med_idt fid) const
2845 if ( _joints.isNotNull() )
2846 _joints->writeLL(fid);
2850 * \brief Load joints in a file or use provided ones
2852 //================================================================================
2854 * \brief Load joints in a file or use provided ones
2855 * \param [in] fid - MED file descriptor
2856 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2857 * Usually this joints are those just read by another iteration
2858 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2860 //================================================================================
2862 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2864 if ( toUseInstedOfReading )
2865 setJoints( toUseInstedOfReading );
2867 _joints = MEDFileJoints::New( fid, _name );
2870 void MEDFileMesh::loadEquivalences(med_idt fid)
2872 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2874 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2877 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2879 const MEDFileEquivalences *equiv(other._equiv);
2881 _equiv=equiv->deepCopy(this);
2884 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2886 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2887 if(!thisEq && !otherEq)
2889 if(thisEq && otherEq)
2890 return thisEq->isEqual(otherEq,what);
2893 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2898 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2900 const MEDFileEquivalences *equiv(_equiv);
2903 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2904 _equiv->getRepr(oss);
2907 void MEDFileMesh::checkCartesian() const
2909 if(getAxisType()!=AX_CART)
2911 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()) << ").";
2912 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2913 oss << " - call setAxisType(AX_CART)" << std::endl;
2914 oss << " - call cartesianize()";
2915 throw INTERP_KERNEL::Exception(oss.str().c_str());
2920 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2922 int MEDFileMesh::getNumberOfJoints() const
2924 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2928 * \brief Return joints with all adjacent mesh domains
2930 MEDFileJoints * MEDFileMesh::getJoints() const
2932 return const_cast<MEDFileJoints*>(& (*_joints));
2935 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2937 if ( joints != _joints )
2946 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2948 * \sa loadPartUMeshFromFile
2950 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2952 MEDFileUMeshL2 loaderl2;
2953 MEDCoupling::MEDCouplingMeshType meshType;
2956 MEDCoupling::MEDCouplingAxisType axType;
2957 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2958 setAxisType(axType);
2959 if(meshType!=UNSTRUCTURED)
2961 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2962 throw INTERP_KERNEL::Exception(oss.str().c_str());
2964 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2965 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2966 // Structure element part...
2969 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2970 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2974 _elt_str.resize(nModels);
2975 for(int i=0;i<nModels;i++)
2976 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2979 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2981 int lev=loaderl2.getNumberOfLevels();
2983 for(int i=0;i<lev;i++)
2985 if(!loaderl2.emptyLev(i))
2986 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2990 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2992 setName(loaderl2.getName());
2993 setDescription(loaderl2.getDescription());
2994 setUnivName(loaderl2.getUnivName());
2995 setIteration(loaderl2.getIteration());
2996 setOrder(loaderl2.getOrder());
2997 setTimeValue(loaderl2.getTime());
2998 setTimeUnit(loaderl2.getTimeUnit());
2999 _coords=loaderl2.getCoords();
3000 if(!mrs || mrs->isNodeFamilyFieldReading())
3001 _fam_coords=loaderl2.getCoordsFamily();
3002 if(!mrs || mrs->isNodeNumFieldReading())
3003 _num_coords=loaderl2.getCoordsNum();
3004 if(!mrs || mrs->isNodeNameFieldReading())
3005 _name_coords=loaderl2.getCoordsName();
3006 if(!mrs || mrs->isGlobalNodeNumFieldReading())
3007 _global_num_coords=loaderl2.getCoordsGlobalNum();
3008 _part_coords=loaderl2.getPartDefOfCoo();
3012 MEDFileUMesh::~MEDFileUMesh()
3016 void MEDFileUMesh::writeMeshLL(med_idt fid) const
3018 const DataArrayDouble *coo=_coords;
3019 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3020 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3021 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3022 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3023 int spaceDim=coo?coo->getNumberOfComponents():0;
3026 mdim=getMeshDimension();
3027 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3028 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3029 for(int i=0;i<spaceDim;i++)
3031 std::string info=coo->getInfoOnComponent(i);
3033 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3034 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
3035 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
3037 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
3039 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
3040 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
3041 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
3042 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3043 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3044 (*it)->write(fid,meshName,mdim);
3045 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
3049 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
3050 * \return std::vector<int> - a sequence of the relative dimensions.
3052 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
3054 std::vector<int> ret;
3056 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3057 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3064 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
3065 * \return std::vector<int> - a sequence of the relative dimensions.
3067 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
3069 std::vector<int> ret0=getNonEmptyLevels();
3070 if((const DataArrayDouble *) _coords)
3072 std::vector<int> ret(ret0.size()+1);
3074 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3080 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
3082 std::vector<int> ret;
3083 const DataArrayInt *famCoo(_fam_coords);
3087 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3089 const MEDFileUMeshSplitL1 *cur(*it);
3091 if(cur->getFamilyField())
3097 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3099 std::vector<int> ret;
3100 if(_num_coords.isNotNull())
3103 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3105 const MEDFileUMeshSplitL1 *cur(*it);
3107 if(cur->getNumberField())
3113 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3115 std::vector<int> ret;
3116 const DataArrayAsciiChar *nameCoo(_name_coords);
3120 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3122 const MEDFileUMeshSplitL1 *cur(*it);
3124 if(cur->getNameField())
3131 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3132 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3133 * \param [in] fams - the name of the family of interest.
3134 * \return std::vector<int> - a sequence of the relative dimensions.
3136 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3138 std::vector<int> ret;
3139 std::vector<int> levs(getNonEmptyLevels());
3140 std::vector<int> famIds(getFamiliesIds(fams));
3141 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3142 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3148 * Returns all relative mesh levels (including nodes) where given families are defined.
3149 * \param [in] fams - the names of the families of interest.
3150 * \return std::vector<int> - a sequence of the relative dimensions.
3152 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3154 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
3155 const DataArrayInt *famCoords(_fam_coords);
3158 std::vector<int> famIds(getFamiliesIds(fams));
3159 if(famCoords->presenceOfValue(famIds))
3161 std::vector<int> ret(ret0.size()+1);
3163 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3170 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3172 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3173 if((const DataArrayInt *)_fam_coords)
3175 int val=_fam_coords->getMaxValue(tmp);
3176 ret=std::max(ret,std::abs(val));
3178 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3180 if((const MEDFileUMeshSplitL1 *)(*it))
3182 const DataArrayInt *da=(*it)->getFamilyField();
3185 int val=da->getMaxValue(tmp);
3186 ret=std::max(ret,std::abs(val));
3193 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3195 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3196 if((const DataArrayInt *)_fam_coords)
3198 int val=_fam_coords->getMaxValue(tmp);
3199 ret=std::max(ret,val);
3201 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3203 if((const MEDFileUMeshSplitL1 *)(*it))
3205 const DataArrayInt *da=(*it)->getFamilyField();
3208 int val=da->getMaxValue(tmp);
3209 ret=std::max(ret,val);
3216 int MEDFileUMesh::getMinFamilyIdInArrays() const
3218 int ret=std::numeric_limits<int>::max(),tmp=-1;
3219 if((const DataArrayInt *)_fam_coords)
3221 int val=_fam_coords->getMinValue(tmp);
3222 ret=std::min(ret,val);
3224 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3226 if((const MEDFileUMeshSplitL1 *)(*it))
3228 const DataArrayInt *da=(*it)->getFamilyField();
3231 int val=da->getMinValue(tmp);
3232 ret=std::min(ret,val);
3240 * Returns the dimension on cells in \a this mesh.
3241 * \return int - the mesh dimension.
3242 * \throw If there are no cells in this mesh.
3244 int MEDFileUMesh::getMeshDimension() const
3247 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3248 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3249 return (*it)->getMeshDimension()+lev;
3250 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3254 * Returns the space dimension of \a this mesh that is equal to number of components in
3255 * the node coordinates array.
3256 * \return int - the space dimension of \a this mesh.
3257 * \throw If the node coordinates array is not available.
3259 int MEDFileUMesh::getSpaceDimension() const
3261 const DataArrayDouble *coo=_coords;
3263 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3264 return coo->getNumberOfComponents();
3268 * Returns a string describing \a this mesh.
3269 * \return std::string - the mesh information string.
3271 std::string MEDFileUMesh::simpleRepr() const
3273 std::ostringstream oss;
3274 oss << MEDFileMesh::simpleRepr();
3275 const DataArrayDouble *coo=_coords;
3276 oss << "- The dimension of the space is ";
3277 static const char MSG1[]= "*** NO COORDS SET ***";
3278 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3280 oss << _coords->getNumberOfComponents() << std::endl;
3282 oss << MSG1 << std::endl;
3283 oss << "- Type of the mesh : UNSTRUCTURED\n";
3284 oss << "- Number of nodes : ";
3286 oss << _coords->getNumberOfTuples() << std::endl;
3288 oss << MSG1 << std::endl;
3289 std::size_t nbOfLev=_ms.size();
3290 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3291 for(std::size_t i=0;i<nbOfLev;i++)
3293 const MEDFileUMeshSplitL1 *lev=_ms[i];
3294 oss << " - Level #" << -((int) i) << " has dimension : ";
3297 oss << lev->getMeshDimension() << std::endl;
3298 lev->simpleRepr(oss);
3301 oss << MSG2 << std::endl;
3303 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3306 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3307 oss << "- Names of coordinates :" << std::endl;
3308 std::vector<std::string> vars=coo->getVarsOnComponent();
3309 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3310 oss << std::endl << "- Units of coordinates : " << std::endl;
3311 std::vector<std::string> units=coo->getUnitsOnComponent();
3312 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3314 oss << std::endl << std::endl;
3316 getEquivalencesRepr(oss);
3321 * Returns a full textual description of \a this mesh.
3322 * \return std::string - the string holding the mesh description.
3324 std::string MEDFileUMesh::advancedRepr() const
3326 return simpleRepr();
3330 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3331 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3332 * \return int - the number of entities.
3333 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3335 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3337 if(meshDimRelToMaxExt==1)
3339 if(!((const DataArrayDouble *)_coords))
3340 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3341 return _coords->getNumberOfTuples();
3343 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3347 * Returns the family field for mesh entities of a given dimension.
3348 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3349 * \return const DataArrayInt * - the family field. It is an array of ids of families
3350 * each mesh entity belongs to. It can be \c NULL.
3352 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3354 if(meshDimRelToMaxExt==1)
3356 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3357 return l1->getFamilyField();
3360 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3362 if(meshDimRelToMaxExt==1)
3364 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3365 return l1->getFamilyField();
3369 * Returns the optional numbers of mesh entities of a given dimension.
3370 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3371 * \return const DataArrayInt * - the array of the entity numbers.
3372 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3374 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3376 if(meshDimRelToMaxExt==1)
3378 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3379 return l1->getNumberField();
3382 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3384 if(meshDimRelToMaxExt==1)
3385 return _name_coords;
3386 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3387 return l1->getNameField();
3390 MCAuto<DataArrayInt> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3392 if(meshDimRelToMaxExt!=1)
3393 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3394 return _global_num_coords;
3398 * 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).
3400 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3401 * \param [in] gt - The input geometric type for which the part definition is requested.
3402 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3404 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3406 if(meshDimRelToMaxExt==1)
3407 return _part_coords;
3408 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3409 return l1->getPartDef(gt);
3412 int MEDFileUMesh::getNumberOfNodes() const
3414 const DataArrayDouble *coo(_coords);
3416 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3417 return coo->getNumberOfTuples();
3420 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3422 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3423 return l1->getNumberOfCells();
3426 bool MEDFileUMesh::hasImplicitPart() const
3431 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3433 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3436 void MEDFileUMesh::releaseImplicitPartIfAny() const
3440 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3442 std::size_t sz(st.getNumberOfItems());
3443 for(std::size_t i=0;i<sz;i++)
3445 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3446 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3447 if(st[i].getPflName().empty())
3448 m->computeNodeIdsAlg(nodesFetched);
3451 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3452 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3453 m2->computeNodeIdsAlg(nodesFetched);
3458 MEDFileMesh *MEDFileUMesh::cartesianize() const
3460 if(getAxisType()==AX_CART)
3463 return const_cast<MEDFileUMesh *>(this);
3467 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3468 const DataArrayDouble *coords(_coords);
3470 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3471 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3472 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3473 if((const MEDFileUMeshSplitL1 *)(*it))
3474 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3475 ret->_coords=coordsCart;
3476 ret->setAxisType(AX_CART);
3481 bool MEDFileUMesh::presenceOfStructureElements() const
3483 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3484 if((*it).isNotNull())
3489 void MEDFileUMesh::killStructureElements()
3495 * Returns the optional numbers of mesh entities of a given dimension transformed using
3496 * DataArrayInt::invertArrayN2O2O2N().
3497 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3498 * \return const DataArrayInt * - the array of the entity numbers transformed using
3499 * DataArrayInt::invertArrayN2O2O2N().
3500 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3502 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3504 if(meshDimRelToMaxExt==1)
3506 if(_num_coords.isNull())
3507 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3508 return _rev_num_coords;
3510 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3511 return l1->getRevNumberField();
3515 * Returns a pointer to the node coordinates array of \a this mesh \b without
3516 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3518 DataArrayDouble *MEDFileUMesh::getCoords() const
3521 MCAuto<DataArrayDouble> tmp(_coords);
3522 if((DataArrayDouble *)tmp)
3530 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3531 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3533 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3534 * \param [in] grp - the name of the group whose mesh entities are included in the
3536 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3537 * according to the optional numbers of entities, if available.
3538 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3539 * delete this mesh using decrRef() as it is no more needed.
3540 * \throw If the name of a nonexistent group is specified.
3541 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3543 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3546 synchronizeTinyInfoOnLeaves();
3547 std::vector<std::string> tmp(1);
3549 return getGroups(meshDimRelToMaxExt,tmp,renum);
3553 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3554 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3556 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3557 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3559 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3560 * according to the optional numbers of entities, if available.
3561 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3562 * delete this mesh using decrRef() as it is no more needed.
3563 * \throw If a name of a nonexistent group is present in \a grps.
3564 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3566 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3569 synchronizeTinyInfoOnLeaves();
3570 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3571 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3572 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3573 zeRet->setName(grps[0]);
3574 return zeRet.retn();
3578 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3579 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3581 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3582 * \param [in] fam - the name of the family whose mesh entities are included in the
3584 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3585 * according to the optional numbers of entities, if available.
3586 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3587 * delete this mesh using decrRef() as it is no more needed.
3588 * \throw If a name of a nonexistent family is present in \a grps.
3589 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3591 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3594 synchronizeTinyInfoOnLeaves();
3595 std::vector<std::string> tmp(1);
3597 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3601 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3602 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3604 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3605 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3607 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3608 * according to the optional numbers of entities, if available.
3609 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3610 * delete this mesh using decrRef() as it is no more needed.
3611 * \throw If a name of a nonexistent family is present in \a fams.
3612 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3614 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3617 synchronizeTinyInfoOnLeaves();
3618 if(meshDimRelToMaxExt==1)
3620 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3621 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3622 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3626 std::vector<int> famIds=getFamiliesIds(fams);
3627 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3628 MCAuto<MEDCouplingUMesh> zeRet;
3630 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3632 zeRet=l1->getFamilyPart(0,0,renum);
3633 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3634 zeRet->setName(fams[0]);
3635 return zeRet.retn();
3639 * Returns ids of mesh entities contained in given families of a given dimension.
3640 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3642 * \param [in] fams - the names of the families of interest.
3643 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3644 * returned instead of ids.
3645 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3646 * numbers, if available and required, of mesh entities of the families. The caller
3647 * is to delete this array using decrRef() as it is no more needed.
3648 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3650 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3652 std::vector<int> famIds=getFamiliesIds(fams);
3653 if(meshDimRelToMaxExt==1)
3655 if((const DataArrayInt *)_fam_coords)
3657 MCAuto<DataArrayInt> da;
3659 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3661 da=_fam_coords->findIdsEqualList(0,0);
3663 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3668 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3670 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3672 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3674 return l1->getFamilyPartArr(0,0,renum);
3678 * Returns a MEDCouplingUMesh of a given relative dimension.
3679 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3680 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3681 * To build a valid MEDCouplingUMesh from the returned one in this case,
3682 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3683 * \param [in] meshDimRelToMax - the relative dimension of interest.
3684 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3685 * optional numbers of mesh entities.
3686 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3687 * delete using decrRef() as it is no more needed.
3688 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3690 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3693 synchronizeTinyInfoOnLeaves();
3694 if(meshDimRelToMaxExt==1)
3698 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3699 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3700 umesh->setCoords(cc);
3701 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3702 umesh->setName(getName());
3706 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3707 return l1->getWholeMesh(renum);
3710 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3712 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3713 return l1->getDistributionOfTypes();
3717 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3718 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3719 * optional numbers of mesh entities.
3720 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3721 * delete using decrRef() as it is no more needed.
3722 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3724 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3726 return getMeshAtLevel(0,renum);
3730 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3731 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3732 * optional numbers of mesh entities.
3733 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3734 * delete using decrRef() as it is no more needed.
3735 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3737 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3739 return getMeshAtLevel(-1,renum);
3743 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3744 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3745 * optional numbers of mesh entities.
3746 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3747 * delete using decrRef() as it is no more needed.
3748 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3750 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3752 return getMeshAtLevel(-2,renum);
3756 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3757 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3758 * optional numbers of mesh entities.
3759 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3760 * delete using decrRef() as it is no more needed.
3761 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3763 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3765 return getMeshAtLevel(-3,renum);
3769 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3770 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3771 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3772 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3774 void MEDFileUMesh::forceComputationOfParts() const
3776 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3778 const MEDFileUMeshSplitL1 *elt(*it);
3780 elt->forceComputationOfParts();
3785 * This method returns a vector of mesh parts containing each exactly one geometric type.
3786 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3787 * This method is only for memory aware users.
3788 * The returned pointers are **NOT** new object pointer. No need to mange them.
3790 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3793 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3794 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3798 * This method returns the part of \a this having the geometric type \a gt.
3799 * If such part is not existing an exception will be thrown.
3800 * The returned pointer is **NOT** new object pointer. No need to mange it.
3802 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3805 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3806 int lev=(int)cm.getDimension()-getMeshDimension();
3807 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3808 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3812 * This method returns for each geo types in \a this number of cells with this geo type.
3813 * 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.
3814 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3816 * \sa getDistributionOfTypes
3818 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3820 std::vector< std::pair<int,int> > ret;
3821 std::vector<int> nel(getNonEmptyLevels());
3822 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3824 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3825 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3827 int nbCells(getNumberOfCellsWithType(*it1));
3828 ret.push_back(std::pair<int,int>(*it1,nbCells));
3831 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3836 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3837 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3839 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3841 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3842 return sp->getGeoTypes();
3845 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3847 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3848 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3849 return sp->getNumberOfCellsWithType(ct);
3853 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3854 * \param [in] gt - the geometric type for which the family field is asked.
3855 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3856 * delete using decrRef() as it is no more needed.
3857 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3859 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3861 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3862 int lev=(int)cm.getDimension()-getMeshDimension();
3863 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3864 return sp->extractFamilyFieldOnGeoType(gt);
3868 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3869 * \param [in] gt - the geometric type for which the number field is asked.
3870 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3871 * delete using decrRef() as it is no more needed.
3872 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3874 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3876 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3877 int lev=(int)cm.getDimension()-getMeshDimension();
3878 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3879 return sp->extractNumberFieldOnGeoType(gt);
3883 * This method returns for specified geometric type \a gt the relative level to \a this.
3884 * If the relative level is empty an exception will be thrown.
3886 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3888 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3889 int ret((int)cm.getDimension()-getMeshDimension());
3890 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3894 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3896 if(meshDimRelToMaxExt==1)
3897 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3898 if(meshDimRelToMaxExt>1)
3899 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3900 int tracucedRk=-meshDimRelToMaxExt;
3901 if(tracucedRk>=(int)_ms.size())
3902 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3903 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3904 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3905 return _ms[tracucedRk];
3908 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3910 if(meshDimRelToMaxExt==1)
3911 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3912 if(meshDimRelToMaxExt>1)
3913 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3914 int tracucedRk=-meshDimRelToMaxExt;
3915 if(tracucedRk>=(int)_ms.size())
3916 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3917 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3918 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3919 return _ms[tracucedRk];
3922 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3924 if(-meshDimRelToMax>=(int)_ms.size())
3925 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3927 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3929 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3931 int ref=(*it)->getMeshDimension();
3932 if(ref+i!=meshDim-meshDimRelToMax)
3933 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3939 * Sets the node coordinates array of \a this mesh.
3940 * \param [in] coords - the new node coordinates array.
3941 * \throw If \a coords == \c NULL.
3943 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3946 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3947 if(coords==(DataArrayDouble *)_coords)
3949 coords->checkAllocated();
3950 int nbOfTuples(coords->getNumberOfTuples());
3951 _coords.takeRef(coords);
3952 _fam_coords=DataArrayInt::New();
3953 _fam_coords->alloc(nbOfTuples,1);
3954 _fam_coords->fillWithZero();
3955 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3956 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3957 if((MEDFileUMeshSplitL1 *)(*it))
3958 (*it)->setCoords(coords);
3962 * Change coords without changing anything concerning families and numbering on nodes.
3964 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3967 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3968 if(coords==(DataArrayDouble *)_coords)
3970 coords->checkAllocated();
3971 int nbOfTuples(coords->getNumberOfTuples());
3972 if(_coords.isNull())
3979 int oldNbTuples(_coords->getNumberOfTuples());
3980 if(oldNbTuples!=nbOfTuples)
3981 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3985 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3986 if((MEDFileUMeshSplitL1 *)(*it))
3987 (*it)->setCoords(coords);
3991 * Removes all groups of a given dimension in \a this mesh.
3992 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3993 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3995 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3997 if(meshDimRelToMaxExt==1)
3999 if((DataArrayInt *)_fam_coords)
4000 _fam_coords->fillWithZero();
4003 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
4004 l1->eraseFamilyField();
4009 * Removes all families with ids not present in the family fields of \a this mesh.
4011 void MEDFileUMesh::optimizeFamilies()
4013 std::vector<int> levs=getNonEmptyLevelsExt();
4014 std::set<int> allFamsIds;
4015 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4017 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
4018 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
4020 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
4023 std::set<std::string> famNamesToKill;
4024 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4026 if(allFamsIds.find((*it).second)!=allFamsIds.end())
4027 famNamesToKill.insert((*it).first);
4029 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
4030 _families.erase(*it);
4031 std::vector<std::string> grpNamesToKill;
4032 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
4034 std::vector<std::string> tmp;
4035 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
4037 if(famNamesToKill.find(*it2)==famNamesToKill.end())
4038 tmp.push_back(*it2);
4043 tmp.push_back((*it).first);
4045 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
4050 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
4051 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
4052 * The boundary is built according to the following method:
4053 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
4054 * coordinates array is extended).
4055 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
4056 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
4057 * might not be duplicated at all.
4058 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
4059 * other side of the group is no more a neighbor)
4060 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
4061 * bordering the newly created boundary use the newly computed nodes.
4062 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
4063 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
4065 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
4066 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
4068 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
4069 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
4070 * \sa clearNodeAndCellNumbers()
4072 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
4073 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
4075 typedef MCAuto<MEDCouplingUMesh> MUMesh;
4076 typedef MCAuto<DataArrayInt> DAInt;
4078 std::vector<int> levs=getNonEmptyLevels();
4079 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
4080 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
4081 MUMesh m0=getMeshAtLevel(0);
4082 MUMesh m1=getMeshAtLevel(-1);
4083 int nbNodes=m0->getNumberOfNodes();
4084 MUMesh m11=getGroup(-1,grpNameM1);
4085 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
4086 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
4087 DAInt nodeIdsToDuplicate(tmp00);
4088 DAInt cellsToModifyConn0(tmp11);
4089 DAInt cellsToModifyConn1(tmp22);
4090 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4091 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4092 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
4093 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4094 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4095 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4096 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4097 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
4098 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4099 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4100 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4101 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4102 DAInt grpIds=getGroupArr(-1,grpNameM1);
4103 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4104 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4105 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4106 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4107 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4108 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4109 m0->setCoords(tmp0->getCoords());
4110 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4111 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4112 m1->setCoords(m0->getCoords());
4113 _coords=m0->getCoords(); _coords->incrRef();
4114 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4115 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4116 DataArrayInt * duplCells;
4117 m1->areCellsIncludedIn(m11, 0, duplCells);
4118 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4119 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4120 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4121 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4122 DAInt szOfCellGrpOfSameType(tmp00);
4123 DAInt idInMsOfCellGrpOfSameType(tmp11);
4125 newm1->setName(getName());
4126 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
4128 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4129 DAInt newFam=DataArrayInt::New();
4130 newFam->alloc(newm1->getNumberOfCells(),1);
4131 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4132 // Positive ID for family of nodes, negative for all the rest.
4134 if (m1->getMeshDimension() == 0)
4135 idd=getMaxFamilyId()+1;
4137 idd=getMinFamilyId()-1;
4138 int globStart=0,start=0,end,globEnd;
4139 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4140 for(int i=0;i<nbOfChunks;i++)
4142 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4143 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4145 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4146 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4147 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4152 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4156 newm1->setCoords(getCoords());
4157 setMeshAtLevel(-1,newm1);
4158 setFamilyFieldArr(-1,newFam);
4159 std::string grpName2(grpNameM1); grpName2+="_dup";
4160 addFamily(grpName2,idd);
4161 addFamilyOnGrp(grpName2,grpName2);
4166 int newNbOfNodes=getCoords()->getNumberOfTuples();
4167 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
4168 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4169 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4173 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4175 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4176 it != _ms.end(); it++)
4179 (*it)->_rev_num = 0;
4181 nodesDuplicated=nodeIdsToDuplicate.retn();
4182 cellsModified=cellsToModifyConn0.retn();
4183 cellsNotModified=cellsToModifyConn1.retn();
4186 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4187 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4190 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4191 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4192 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4194 * \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.
4195 * 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.
4197 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4199 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4200 std::vector<int> levs=getNonEmptyLevels();
4202 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4203 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4206 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4208 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4209 std::vector<int> code1=m->getDistributionOfTypes();
4210 end=PutInThirdComponentOfCodeOffset(code1,start);
4211 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4212 bool hasChanged=m->unPolyze();
4213 DataArrayInt *fake=0;
4214 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4215 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4217 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4220 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4221 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4223 MCAuto<DataArrayInt> famField2,numField2;
4224 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4225 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4226 setMeshAtLevel(*it,m);
4227 std::vector<int> code2=m->getDistributionOfTypes();
4228 end=PutInThirdComponentOfCodeOffset(code2,start);
4229 newCode.insert(newCode.end(),code2.begin(),code2.end());
4231 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4235 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4236 setFamilyFieldArr(*it,newFamField);
4240 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4241 setRenumFieldArr(*it,newNumField);
4246 newCode.insert(newCode.end(),code1.begin(),code1.end());
4252 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4253 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4254 o2nRenumCell=o2nRenumCellRet.retn();
4259 /*! \cond HIDDEN_ITEMS */
4260 struct MEDLoaderAccVisit1
4262 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4263 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4264 int _new_nb_of_nodes;
4269 * Array returned is the correspondence in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
4270 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4271 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4272 * -1 values in returned array means that the corresponding old node is no more used.
4274 * \return newly allocated array containing correspondence in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
4275 * is modified in \a this.
4276 * \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
4279 DataArrayInt *MEDFileUMesh::zipCoords()
4281 const DataArrayDouble *coo(getCoords());
4283 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4284 int nbOfNodes(coo->getNumberOfTuples());
4285 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4286 std::vector<int> neLevs(getNonEmptyLevels());
4287 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4289 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4290 if(zeLev->isMeshStoredSplitByType())
4292 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4293 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4295 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4299 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4300 mesh->computeNodeIdsAlg(nodeIdsInUse);
4303 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4304 if(nbrOfNodesInUse==nbOfNodes)
4305 return 0;//no need to update _part_coords
4306 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4307 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4308 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4309 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4310 MCAuto<DataArrayInt> newFamCoords;
4311 MCAuto<DataArrayAsciiChar> newNameCoords;
4312 if((const DataArrayInt *)_fam_coords)
4313 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4314 MCAuto<DataArrayInt> newNumCoords,newGlobalNumCoords;
4315 if(_num_coords.isNotNull())
4316 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4317 if(_global_num_coords.isNotNull())
4318 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4319 if(_name_coords.isNotNull())
4320 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4321 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4322 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4324 if((MEDFileUMeshSplitL1*)*it)
4326 (*it)->renumberNodesInConn(ret->begin());
4327 (*it)->setCoords(_coords);
4330 // updates _part_coords
4331 const PartDefinition *pc(_part_coords);
4334 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4335 _part_coords=tmpPD->composeWith(pc);
4341 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4342 * The extraction of \a this is specified by the extractDef \a input map.
4343 * This map tells for each level of cells, the cells kept in the extraction.
4345 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4346 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4348 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4350 std::vector<int> levs(getNonEmptyLevels());
4351 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4352 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4355 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4356 if((*it).second.isNull())
4357 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4360 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4362 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4363 throw INTERP_KERNEL::Exception(oss.str());
4365 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4366 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4367 mPart->computeNodeIdsAlg(fetchedNodes);
4369 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4373 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4375 * \return - a new reference of MEDFileUMesh
4376 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4378 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4380 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4381 std::vector<int> levs(getNonEmptyLevels());
4382 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4385 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4386 if((*it).second.isNull())
4387 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4390 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4392 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4393 throw INTERP_KERNEL::Exception(oss.str());
4395 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4396 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4397 ret->setMeshAtLevel((*it).first,mPart);
4398 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4401 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4402 ret->setFamilyFieldArr((*it).first,famPart);
4406 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4407 ret->setFamilyFieldArr((*it).first,numPart);
4410 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4411 if(it2!=extractDef.end())
4413 const DataArrayDouble *coo(ret->getCoords());
4415 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4416 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4417 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4418 ret->setCoords(cooPart);
4419 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4422 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4423 ret->setFamilyFieldArr(1,famPart);
4427 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4428 ret->setFamilyFieldArr(1,numPart);
4430 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4434 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4435 m->renumberNodesInConn(o2nNodes->begin());
4436 ret->setMeshAtLevel((*it3).first,m);
4443 * This method performs an extrusion along a path defined by \a m1D.
4444 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4445 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4446 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4447 * This method scans all levels in \a this
4448 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4450 * \param [in] m1D - the mesh defining the extrusion path.
4451 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4452 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4454 * \sa MEDCouplingUMesh::buildExtrudedMesh
4456 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4459 if(getMeshDimension()!=2)
4460 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4461 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4462 m1D->checkConsistencyLight();
4463 if(m1D->getMeshDimension()!=1)
4464 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4465 int nbRep(m1D->getNumberOfCells());
4466 std::vector<int> levs(getNonEmptyLevels());
4467 std::vector<std::string> grps(getGroupsNames());
4468 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4469 DataArrayDouble *coords(0);
4470 std::size_t nbOfLevsOut(levs.size()+1);
4471 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4472 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4474 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4475 item=item->clone(false);
4476 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4477 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4478 tmp->changeSpaceDimension(3+(*lev),0.);
4479 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4480 zeList.push_back(elt);
4482 coords=elt->getCoords();
4485 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4486 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4488 (*it)->setName(getName());
4489 (*it)->setCoords(coords);
4491 for(std::size_t ii=0;ii!=zeList.size();ii++)
4494 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4497 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4498 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4499 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4500 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4501 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4502 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4503 std::vector<const MEDCouplingUMesh *> elts(3);
4504 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4505 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4506 elt->setName(getName());
4509 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4510 ret->setMeshAtLevel(lev,elt);
4512 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4513 endLev=endLev->clone(false); endLev->setCoords(coords);
4514 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4515 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4516 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4517 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4518 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4519 endLev->setName(getName());
4520 ret->setMeshAtLevel(levs.back()-1,endLev);
4522 for(std::size_t ii=0;ii!=zeList.size();ii++)
4525 std::vector< MCAuto<DataArrayInt> > outGrps;
4526 std::vector< const DataArrayInt * > outGrps2;
4529 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4531 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4532 if(!grpArr->empty())
4534 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4535 int offset0(zeList[ii]->getNumberOfCells());
4536 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4537 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4538 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4539 grpArr2->setName(oss.str());
4540 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4541 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4542 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4543 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4548 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4550 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4551 if(!grpArr->empty())
4553 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4554 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4555 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4556 for(int iii=0;iii<nbRep;iii++)
4558 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4559 grpArrs2[iii]=grpArrs[iii];
4561 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4562 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4563 std::ostringstream grpName; grpName << *grp << "_extruded";
4564 grpArrExt->setName(grpName.str());
4565 outGrps.push_back(grpArrExt);
4566 outGrps2.push_back(grpArrExt);
4569 ret->setGroupsAtLevel(lev,outGrps2);
4571 std::vector< MCAuto<DataArrayInt> > outGrps;
4572 std::vector< const DataArrayInt * > outGrps2;
4573 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4575 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4576 if(grpArr1->empty())
4578 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4579 std::ostringstream grpName; grpName << *grp << "_top";
4580 grpArr2->setName(grpName.str());
4581 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4582 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4583 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4585 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4590 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4591 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4592 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4594 * \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
4595 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4596 * \param [in] eps - detection threshold for coordinates.
4597 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4599 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4601 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4604 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4605 int initialNbNodes(getNumberOfNodes());
4606 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4607 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4609 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4611 DataArrayDouble *zeCoords(m0->getCoords());
4612 ret->setMeshAtLevel(0,m0);
4613 std::vector<int> levs(getNonEmptyLevels());
4614 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4617 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4618 ret->setFamilyFieldArr(0,famFieldCpy);
4620 famField=getFamilyFieldAtLevel(1);
4623 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4624 fam->fillWithZero();
4625 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4626 ret->setFamilyFieldArr(1,fam);
4628 ret->copyFamGrpMapsFrom(*this);
4629 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4630 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4634 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4635 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4636 if(m1->getMeshDimension()!=0)
4639 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4640 }//kill unused notUsed var
4641 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4643 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4644 MCAuto<DataArrayInt> bSafe(b);
4647 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4648 throw INTERP_KERNEL::Exception(oss.str().c_str());
4650 b->applyLin(1,initialNbNodes);
4651 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4652 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4653 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4654 m1->renumberNodesInConn(renum->begin());
4656 m1->setCoords(zeCoords);
4657 ret->setMeshAtLevel(*lev,m1);
4658 famField=getFamilyFieldAtLevel(*lev);
4661 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4662 ret->setFamilyFieldArr(*lev,famFieldCpy);
4669 * This method converts all quadratic cells in \a this into linear cells.
4670 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4671 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4673 * \param [in] eps - detection threshold for coordinates.
4674 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4676 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4678 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4681 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4682 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4683 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4684 m0->convertQuadraticCellsToLinear();
4686 DataArrayDouble *zeCoords(m0->getCoords());
4687 ret->setMeshAtLevel(0,m0);
4688 std::vector<int> levs(getNonEmptyLevels());
4689 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4692 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4693 ret->setFamilyFieldArr(0,famFieldCpy);
4695 famField=getFamilyFieldAtLevel(1);
4698 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4699 ret->setFamilyFieldArr(1,fam);
4701 ret->copyFamGrpMapsFrom(*this);
4702 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4706 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4707 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4708 m1->convertQuadraticCellsToLinear();
4711 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4712 MCAuto<DataArrayInt> bSafe(b);
4715 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4716 throw INTERP_KERNEL::Exception(oss.str().c_str());
4718 m1->renumberNodesInConn(b->begin());
4719 m1->setCoords(zeCoords);
4720 ret->setMeshAtLevel(*lev,m1);
4721 famField=getFamilyFieldAtLevel(*lev);
4724 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4725 ret->setFamilyFieldArr(*lev,famFieldCpy);
4732 * Computes the symmetry of \a this.
4733 * \return a new object.
4735 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4737 MCAuto<MEDFileUMesh> ret(deepCopy());
4738 DataArrayDouble *myCoo(getCoords());
4741 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4742 ret->setCoordsForced(newCoo);
4748 * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
4749 * merged in such a way that the final mesh contain all of them.
4750 * \return a new object.
4752 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4755 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4756 std::size_t sz(meshes.size()),i(0);
4757 std::vector<const DataArrayDouble *> coos(sz);
4758 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4759 for(auto it=meshes.begin();it!=meshes.end();it++,i++)
4762 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4763 coos[i]=(*it)->getCoords();
4764 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4765 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4767 const MEDFileUMesh *ref(meshes[0]);
4768 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4769 std::vector<int> levs(ref->getNonEmptyLevels());
4770 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4771 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4772 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4773 std::map<std::string,int> famNumMap;
4774 std::map<int, std::string> famNumMap_rev;
4775 std::map<std::string, std::vector<std::string> > grpFamMap;
4776 std::set< MCAuto<DataArrayInt> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
4778 // Identify min family number used:
4780 for(const auto& msh : meshes)
4782 const std::map<std::string,int>& locMap1(msh->getFamilyInfo());
4783 for(const auto& it3 : locMap1)
4784 if(it3.second < min_fam_num)
4785 min_fam_num = it3.second;
4788 for(const auto& msh : meshes)
4790 if(msh->getSpaceDimension()!=spaceDim)
4791 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4792 if(msh->getMeshDimension()!=meshDim)
4793 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4794 if(msh->getNonEmptyLevels()!=levs)
4795 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4797 const std::map<std::string,int>& locMap1(msh->getFamilyInfo());
4798 std::map<std::string, std::string> substitute;
4799 std::map<int, int> substituteN;
4800 bool fam_conflict(false);
4801 for(const auto& it3 : locMap1)
4803 const std::string& famName = it3.first;
4804 int famNum = it3.second;
4805 if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
4807 // Is it used by a group of the current mesh or a group from a previous mesh?
4808 // If not, this is OK (typically -1 familly).
4811 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4812 for(const auto& it4 : locMap2)
4814 const auto& famLst = it4.second;
4815 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4816 { used = true; break; }
4818 // Previous meshes ...
4820 for(const auto& it4 : grpFamMap)
4822 const auto& famLst = it4.second;
4823 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4824 { used = true; break; }
4828 { // Generate a new family name, and a new family number
4829 fam_conflict = true;
4830 std::ostringstream oss;
4831 oss << "Family_" << --min_fam_num; // New ID
4832 std::string new_name(oss.str());
4833 substitute[famName] = new_name;
4834 substituteN[famNum] = min_fam_num;
4835 famNumMap[new_name] = min_fam_num;
4836 famNumMap_rev[min_fam_num] = new_name;
4839 famNumMap[famName] = famNum;
4840 famNumMap_rev[famNum] = famName;
4843 for(const auto& level : levs)
4845 MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
4846 m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
4847 m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
4849 // Family field - substitute new family number if needed:
4852 DataArrayInt* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
4853 mem_cleanup.insert(MCAuto<DataArrayInt>(dai)); // Make sure array will decrRef() at end of method
4854 for (const auto& subN : substituteN)
4855 dai->changeValue(subN.first, subN.second);
4856 m_fam[level].push_back(dai);
4859 m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
4862 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4863 for(const auto& grpItem : locMap2)
4865 const std::string& grpName = grpItem.first;
4866 std::vector<std::string> famLst;
4867 // Substitute family name in group description if needed:
4870 famLst = grpItem.second;
4871 for (const auto& sub : substitute)
4872 std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
4875 famLst = grpItem.second;
4877 // Potentially merge groups (if same name):
4878 const auto& it = grpFamMap.find(grpName);
4879 if (it != grpFamMap.end())
4881 // Group already exists, merge should be done. Normally we whould never
4882 // have twice the same family name in famLstCur and famLst since we dealt with family number
4883 // conflict just above ...
4884 std::vector<std::string>& famLstCur = (*it).second;
4885 famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
4888 grpFamMap[grpName] = famLst;
4891 // Easy part : nodes
4892 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4893 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4894 ret->setCoords(coo);
4895 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4897 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4898 ret->setFamilyFieldArr(1,fam_coo);
4900 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4902 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4903 ret->setRenumFieldArr(1,num_coo);
4906 for(const auto& level : levs)
4908 auto it2(m_mesh.find(level));
4909 if(it2==m_mesh.end())
4910 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4911 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4912 mesh->setCoords(coo); mesh->setName(ref->getName());
4913 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4914 ret->setMeshAtLevel(level,mesh);
4915 auto it3(m_fam.find(level)),it4(m_renum.find(level));
4916 if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
4917 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
4918 if(it4==m_renum.end())
4919 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
4920 // Set new family field if it was defined for all input meshes
4921 const std::vector<const DataArrayInt *>& fams((*it3).second);
4922 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4924 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4925 famm->renumberInPlace(renum->begin());
4926 ret->setFamilyFieldArr(level,famm);
4928 // Set optional number field if defined for all input meshes:
4929 const std::vector<const DataArrayInt *>& renums((*it4).second);
4930 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4932 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4933 renumm->renumberInPlace(renum->begin());
4934 ret->setRenumFieldArr(level,renumm);
4938 ret->setFamilyInfo(famNumMap);
4939 ret->setGroupInfo(grpFamMap);
4940 ret->setName(ref->getName());
4944 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4946 if(getMeshDimension()!=3)
4947 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4948 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4949 if(m3D.isNull() || m2D.isNull())
4950 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4951 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4952 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4956 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4958 clearNonDiscrAttributes();
4959 forceComputationOfParts();
4960 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4961 std::vector<int> layer0;
4962 layer0.push_back(getAxisType());//0 i
4963 layer0.push_back(_order); //1 i
4964 layer0.push_back(_iteration);//2 i
4965 layer0.push_back(getSpaceDimension());//3 i
4966 tinyDouble.push_back(_time);//0 d
4967 tinyStr.push_back(_name);//0 s
4968 tinyStr.push_back(_desc_name);//1 s
4969 for(int i=0;i<getSpaceDimension();i++)
4970 tinyStr.push_back(_coords->getInfoOnComponent(i));
4971 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4972 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4974 tinyStr.push_back((*it).first);
4975 layer0.push_back((*it).second);
4977 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4978 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4980 layer0.push_back((int)(*it0).second.size());
4981 tinyStr.push_back((*it0).first);
4982 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4983 tinyStr.push_back(*it1);
4985 // sizeof(layer0)==4+aa+1+bb layer#0
4986 bigArrayD=_coords;// 0 bd
4987 bigArraysI.push_back(_fam_coords);// 0 bi
4988 bigArraysI.push_back(_num_coords);// 1 bi
4989 const PartDefinition *pd(_part_coords);
4991 layer0.push_back(-1);
4994 std::vector<int> tmp0;
4995 pd->serialize(tmp0,bigArraysI);
4996 tinyInt.push_back(tmp0.size());
4997 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
5000 std::vector<int> layer1;
5001 std::vector<int> levs(getNonEmptyLevels());
5002 layer1.push_back((int)levs.size());// 0 i <- key
5003 layer1.insert(layer1.end(),levs.begin(),levs.end());
5004 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
5006 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
5007 lev->serialize(layer1,bigArraysI);
5009 // put layers all together.
5010 tinyInt.push_back(layer0.size());
5011 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
5012 tinyInt.push_back(layer1.size());
5013 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
5016 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
5017 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5019 int sz0(tinyInt[0]);
5020 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
5021 int sz1(tinyInt[sz0+1]);
5022 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
5024 std::reverse(layer0.begin(),layer0.end());
5025 std::reverse(layer1.begin(),layer1.end());
5026 std::reverse(tinyDouble.begin(),tinyDouble.end());
5027 std::reverse(tinyStr.begin(),tinyStr.end());
5028 std::reverse(bigArraysI.begin(),bigArraysI.end());
5030 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
5031 _order=layer0.back(); layer0.pop_back();
5032 _iteration=layer0.back(); layer0.pop_back();
5033 int spaceDim(layer0.back()); layer0.pop_back();
5034 _time=tinyDouble.back(); tinyDouble.pop_back();
5035 _name=tinyStr.back(); tinyStr.pop_back();
5036 _desc_name=tinyStr.back(); tinyStr.pop_back();
5037 _coords=bigArrayD; _coords->rearrange(spaceDim);
5038 for(int i=0;i<spaceDim;i++)
5040 _coords->setInfoOnComponent(i,tinyStr.back());
5043 int nbOfFams(layer0.back()); layer0.pop_back();
5045 for(int i=0;i<nbOfFams;i++)
5047 _families[tinyStr.back()]=layer0.back();
5048 tinyStr.pop_back(); layer0.pop_back();
5050 int nbGroups(layer0.back()); layer0.pop_back();
5052 for(int i=0;i<nbGroups;i++)
5054 std::string grpName(tinyStr.back()); tinyStr.pop_back();
5055 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
5056 std::vector<std::string> fams(nbOfFamsOnGrp);
5057 for(int j=0;j<nbOfFamsOnGrp;j++)
5059 fams[j]=tinyStr.back(); tinyStr.pop_back();
5061 _groups[grpName]=fams;
5063 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
5064 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
5066 int isPd(layer0.back()); layer0.pop_back();
5069 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
5070 layer0.erase(layer0.begin(),layer0.begin()+isPd);
5071 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
5074 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
5076 int nbLevs(layer1.back()); layer1.pop_back();
5077 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
5079 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
5080 _ms.resize(maxLev+1);
5081 for(int i=0;i<nbLevs;i++)
5085 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
5090 * Adds a group of nodes to \a this mesh.
5091 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5092 * The ids should be sorted and different each other (MED file norm).
5094 * \warning this method can alter default "FAMILLE_ZERO" family.
5095 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5097 * \throw If the node coordinates array is not set.
5098 * \throw If \a ids == \c NULL.
5099 * \throw If \a ids->getName() == "".
5100 * \throw If \a ids does not respect the MED file norm.
5101 * \throw If a group with name \a ids->getName() already exists.
5103 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
5105 const DataArrayDouble *coords(_coords);
5107 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
5108 int nbOfNodes(coords->getNumberOfTuples());
5109 if(_fam_coords.isNull())
5110 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
5112 addGroupUnderground(true,ids,_fam_coords);
5116 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5118 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5119 * The ids should be sorted and different each other (MED file norm).
5121 * \warning this method can alter default "FAMILLE_ZERO" family.
5122 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5124 * \throw If the node coordinates array is not set.
5125 * \throw If \a ids == \c NULL.
5126 * \throw If \a ids->getName() == "".
5127 * \throw If \a ids does not respect the MED file norm.
5128 * \throw If a group with name \a ids->getName() already exists.
5130 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5132 std::vector<int> levs(getNonEmptyLevelsExt());
5133 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
5135 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
5136 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
5138 if(meshDimRelToMaxExt==1)
5139 { addNodeGroup(ids); return ; }
5140 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
5141 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
5142 addGroupUnderground(false,ids,fam);
5146 * Changes a name of a family specified by its id.
5147 * \param [in] id - the id of the family of interest.
5148 * \param [in] newFamName - the new family name.
5149 * \throw If no family with the given \a id exists.
5151 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
5153 std::string oldName=getFamilyNameGivenId(id);
5154 _families.erase(oldName);
5155 _families[newFamName]=id;
5159 * Removes a mesh of a given dimension.
5160 * \param [in] meshDimRelToMax - the relative dimension of interest.
5161 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
5163 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
5165 std::vector<int> levSet=getNonEmptyLevels();
5166 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
5167 if(it==levSet.end())
5168 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
5169 int pos=(-meshDimRelToMax);
5174 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
5175 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5176 * \param [in] m - the new mesh to set.
5177 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5179 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5180 * another node coordinates array.
5181 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5182 * to the existing meshes of other levels of \a this mesh.
5184 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5186 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5187 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5191 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5192 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5193 * \param [in] m - the new mesh to set.
5194 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5195 * writing \a this mesh in a MED file.
5196 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5198 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5199 * another node coordinates array.
5200 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5201 * to the existing meshes of other levels of \a this mesh.
5203 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5205 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5206 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5209 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5211 dealWithTinyInfo(m);
5212 std::vector<int> levSet=getNonEmptyLevels();
5213 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5215 if((DataArrayDouble *)_coords==0)
5217 DataArrayDouble *c=m->getCoords();
5222 if(m->getCoords()!=_coords)
5223 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5224 int sz=(-meshDimRelToMax)+1;
5225 if(sz>=(int)_ms.size())
5227 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5231 return _ms[-meshDimRelToMax];
5235 * This method allows to set at once the content of different levels in \a this.
5236 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5238 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5239 * \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.
5240 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5242 * \throw If \a there is a null pointer in \a ms.
5243 * \sa MEDFileUMesh::setMeshAtLevel
5245 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5249 const MEDCouplingUMesh *mRef=ms[0];
5251 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5252 std::string name(mRef->getName());
5253 const DataArrayDouble *coo(mRef->getCoords());
5256 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5258 const MEDCouplingUMesh *cur(*it);
5260 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5261 if(coo!=cur->getCoords())
5262 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5263 int mdim=cur->getMeshDimension();
5264 zeDim=std::max(zeDim,mdim);
5265 if(s.find(mdim)!=s.end())
5266 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5268 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5270 int mdim=(*it)->getMeshDimension();
5271 setName((*it)->getName());
5272 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5278 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5279 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5280 * The given meshes must share the same node coordinates array.
5281 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5282 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5283 * create in \a this mesh.
5284 * \throw If \a ms is empty.
5285 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5286 * to the existing meshes of other levels of \a this mesh.
5287 * \throw If the meshes in \a ms do not share the same node coordinates array.
5288 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5289 * of the given meshes.
5290 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5291 * \throw If names of some meshes in \a ms are equal.
5292 * \throw If \a ms includes a mesh with an empty name.
5294 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5297 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5298 int sz=(-meshDimRelToMax)+1;
5299 if(sz>=(int)_ms.size())
5301 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5302 DataArrayDouble *coo=checkMultiMesh(ms);
5303 if((DataArrayDouble *)_coords==0)
5309 if((DataArrayDouble *)_coords!=coo)
5310 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5311 std::vector<DataArrayInt *> corr;
5312 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5313 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5314 setMeshAtLevel(meshDimRelToMax,m,renum);
5315 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5316 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5320 * Creates groups at a given level in \a this mesh from a sequence of
5321 * meshes each representing a group.
5322 * The given meshes must share the same node coordinates array.
5323 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5324 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5325 * create in \a this mesh.
5326 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5328 * \throw If \a ms is empty.
5329 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5330 * to the existing meshes of other levels of \a this mesh.
5331 * \throw If the meshes in \a ms do not share the same node coordinates array.
5332 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5333 * of the given meshes.
5334 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5335 * \throw If names of some meshes in \a ms are equal.
5336 * \throw If \a ms includes a mesh with an empty name.
5338 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5341 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5342 int sz=(-meshDimRelToMax)+1;
5343 if(sz>=(int)_ms.size())
5345 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5346 DataArrayDouble *coo=checkMultiMesh(ms);
5347 if((DataArrayDouble *)_coords==0)
5353 if((DataArrayDouble *)_coords!=coo)
5354 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5355 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5356 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5358 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5360 DataArrayInt *arr=0;
5361 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5365 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5366 throw INTERP_KERNEL::Exception(oss.str().c_str());
5369 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5370 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5373 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5375 const DataArrayDouble *ret=ms[0]->getCoords();
5376 int mdim=ms[0]->getMeshDimension();
5377 for(unsigned int i=1;i<ms.size();i++)
5379 ms[i]->checkConsistencyLight();
5380 if(ms[i]->getCoords()!=ret)
5381 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5382 if(ms[i]->getMeshDimension()!=mdim)
5383 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5385 return const_cast<DataArrayDouble *>(ret);
5389 * Sets the family field of a given relative dimension.
5390 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5391 * the family field is set.
5392 * \param [in] famArr - the array of the family field.
5393 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5394 * \throw If \a famArr has an invalid size.
5396 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5398 if(meshDimRelToMaxExt==1)
5405 DataArrayDouble *coo(_coords);
5407 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5408 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5409 _fam_coords.takeRef(famArr);
5412 if(meshDimRelToMaxExt>1)
5413 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5414 int traducedRk=-meshDimRelToMaxExt;
5415 if(traducedRk>=(int)_ms.size())
5416 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5417 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5418 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5419 return _ms[traducedRk]->setFamilyArr(famArr);
5423 * Sets the optional numbers of mesh entities of a given dimension.
5424 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5425 * \param [in] renumArr - the array of the numbers.
5426 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5427 * \throw If \a renumArr has an invalid size.
5429 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5431 if(meshDimRelToMaxExt==1)
5435 _num_coords.nullify();
5436 _rev_num_coords.nullify();
5439 if(_coords.isNull())
5440 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5441 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5442 _num_coords.takeRef(renumArr);
5446 if(meshDimRelToMaxExt>1)
5447 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5448 int traducedRk=-meshDimRelToMaxExt;
5449 if(traducedRk>=(int)_ms.size())
5450 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5451 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5452 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5453 return _ms[traducedRk]->setRenumArr(renumArr);
5457 * Sets the optional names of mesh entities of a given dimension.
5458 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5459 * \param [in] nameArr - the array of the names.
5460 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5461 * \throw If \a nameArr has an invalid size.
5463 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5465 if(meshDimRelToMaxExt==1)
5472 DataArrayDouble *coo(_coords);
5474 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5475 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5476 _name_coords.takeRef(nameArr);
5479 if(meshDimRelToMaxExt>1)
5480 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5481 int traducedRk=-meshDimRelToMaxExt;
5482 if(traducedRk>=(int)_ms.size())
5483 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5484 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5485 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5486 return _ms[traducedRk]->setNameArr(nameArr);
5489 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5491 if(meshDimRelToMaxExt!=1)
5492 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5494 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5495 _global_num_coords.takeRef(globalNumArr);
5498 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5500 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5501 if((const MEDFileUMeshSplitL1 *)(*it))
5502 (*it)->synchronizeTinyInfo(*this);
5506 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5508 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5510 DataArrayInt *arr=_fam_coords;
5512 arr->changeValue(oldId,newId);
5513 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5515 MEDFileUMeshSplitL1 *sp=(*it);
5518 sp->changeFamilyIdArr(oldId,newId);
5523 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5525 std::list< MCAuto<DataArrayInt> > ret;
5526 const DataArrayInt *da(_fam_coords);
5528 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5529 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5531 const MEDFileUMeshSplitL1 *elt(*it);
5534 da=elt->getFamilyField();
5536 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5542 void MEDFileUMesh::computeRevNum() const
5544 if(_num_coords.isNotNull())
5547 int maxValue=_num_coords->getMaxValue(pos);
5548 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5552 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5554 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5557 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5559 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5560 ret.push_back((const DataArrayInt *)_fam_nodes);
5561 ret.push_back((const DataArrayInt *)_num_nodes);
5562 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5563 ret.push_back((const DataArrayInt *)_fam_cells);
5564 ret.push_back((const DataArrayInt *)_num_cells);
5565 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5566 ret.push_back((const DataArrayInt *)_fam_faces);
5567 ret.push_back((const DataArrayInt *)_num_faces);
5568 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5569 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5570 ret.push_back((const DataArrayInt *)_rev_num_cells);
5571 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5575 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5577 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5578 if((const DataArrayInt *)_fam_nodes)
5580 int val=_fam_nodes->getMaxValue(tmp);
5581 ret=std::max(ret,std::abs(val));
5583 if((const DataArrayInt *)_fam_cells)
5585 int val=_fam_cells->getMaxValue(tmp);
5586 ret=std::max(ret,std::abs(val));
5588 if((const DataArrayInt *)_fam_faces)
5590 int val=_fam_faces->getMaxValue(tmp);
5591 ret=std::max(ret,std::abs(val));
5596 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5598 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5599 if((const DataArrayInt *)_fam_nodes)
5601 int val=_fam_nodes->getMaxValue(tmp);
5602 ret=std::max(ret,val);
5604 if((const DataArrayInt *)_fam_cells)
5606 int val=_fam_cells->getMaxValue(tmp);
5607 ret=std::max(ret,val);
5609 if((const DataArrayInt *)_fam_faces)
5611 int val=_fam_faces->getMaxValue(tmp);
5612 ret=std::max(ret,val);
5617 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5619 int ret=std::numeric_limits<int>::max(),tmp=-1;
5620 if((const DataArrayInt *)_fam_nodes)
5622 int val=_fam_nodes->getMinValue(tmp);
5623 ret=std::min(ret,val);
5625 if((const DataArrayInt *)_fam_cells)
5627 int val=_fam_cells->getMinValue(tmp);
5628 ret=std::min(ret,val);
5630 if((const DataArrayInt *)_fam_faces)
5632 int val=_fam_faces->getMinValue(tmp);
5633 ret=std::min(ret,val);
5638 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5640 if(!MEDFileMesh::isEqual(other,eps,what))
5642 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5645 what="Mesh types differ ! This is structured and other is NOT !";
5648 const DataArrayInt *famc1=_fam_nodes;
5649 const DataArrayInt *famc2=otherC->_fam_nodes;
5650 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5652 what="Mismatch of families arr on nodes ! One is defined and not other !";
5657 bool ret=famc1->isEqual(*famc2);
5660 what="Families arr on nodes differ !";
5665 famc2=otherC->_fam_cells;
5666 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5668 what="Mismatch of families arr on cells ! One is defined and not other !";
5673 bool ret=famc1->isEqual(*famc2);
5676 what="Families arr on cells differ !";
5681 famc2=otherC->_fam_faces;
5682 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5684 what="Mismatch of families arr on faces ! One is defined and not other !";
5689 bool ret=famc1->isEqual(*famc2);
5692 what="Families arr on faces differ !";
5697 famc2=otherC->_num_nodes;
5698 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5700 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5705 bool ret=famc1->isEqual(*famc2);
5708 what="Numbering arr on nodes differ !";
5713 famc2=otherC->_num_cells;
5714 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5716 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5721 bool ret=famc1->isEqual(*famc2);
5724 what="Numbering arr on cells differ !";
5729 famc2=otherC->_num_faces;
5730 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5732 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5737 bool ret=famc1->isEqual(*famc2);
5740 what="Numbering arr on faces differ !";
5744 const DataArrayAsciiChar *d1=_names_cells;
5745 const DataArrayAsciiChar *d2=otherC->_names_cells;
5746 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5748 what="Mismatch of naming arr on cells ! One is defined and not other !";
5753 bool ret=d1->isEqual(*d2);
5756 what="Naming arr on cells differ !";
5761 d2=otherC->_names_faces;
5762 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5764 what="Mismatch of naming arr on faces ! One is defined and not other !";
5769 bool ret=d1->isEqual(*d2);
5772 what="Naming arr on faces differ !";
5777 d2=otherC->_names_nodes;
5778 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5780 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5785 bool ret=d1->isEqual(*d2);
5788 what="Naming arr on nodes differ !";
5795 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5797 MEDFileMesh::clearNonDiscrAttributes();
5798 const DataArrayInt *tmp=_fam_nodes;
5800 (const_cast<DataArrayInt *>(tmp))->setName("");
5803 (const_cast<DataArrayInt *>(tmp))->setName("");
5806 (const_cast<DataArrayInt *>(tmp))->setName("");
5809 (const_cast<DataArrayInt *>(tmp))->setName("");
5812 (const_cast<DataArrayInt *>(tmp))->setName("");
5815 (const_cast<DataArrayInt *>(tmp))->setName("");
5819 * Returns ids of mesh entities contained in given families of a given dimension.
5820 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5822 * \param [in] fams - the names of the families of interest.
5823 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5824 * returned instead of ids.
5825 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5826 * numbers, if available and required, of mesh entities of the families. The caller
5827 * is to delete this array using decrRef() as it is no more needed.
5828 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5830 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5832 std::vector<int> famIds(getFamiliesIds(fams));
5833 switch(meshDimRelToMaxExt)
5837 if((const DataArrayInt *)_fam_nodes)
5839 MCAuto<DataArrayInt> da;
5841 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5843 da=_fam_nodes->findIdsEqualList(0,0);
5845 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5850 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5855 if((const DataArrayInt *)_fam_cells)
5857 MCAuto<DataArrayInt> da;
5859 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5861 da=_fam_cells->findIdsEqualList(0,0);
5863 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5868 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5873 if((const DataArrayInt *)_fam_faces)
5875 MCAuto<DataArrayInt> da;
5877 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5879 da=_fam_faces->findIdsEqualList(0,0);
5881 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5886 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5890 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5892 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5896 * Sets the family field of a given relative dimension.
5897 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5898 * the family field is set.
5899 * \param [in] famArr - the array of the family field.
5900 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5901 * \throw If \a famArr has an invalid size.
5902 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5904 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5906 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5908 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5909 switch(meshDimRelToMaxExt)
5913 int nbCells(mesh->getNumberOfCells());
5915 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5921 int nbNodes(mesh->getNumberOfNodes());
5923 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5929 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5931 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5936 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5943 * Sets the optional numbers of mesh entities of a given dimension.
5944 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5945 * \param [in] renumArr - the array of the numbers.
5946 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5947 * \throw If \a renumArr has an invalid size.
5948 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5950 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5952 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5954 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5955 switch(meshDimRelToMaxExt)
5959 int nbCells=mesh->getNumberOfCells();
5960 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5961 _num_cells=renumArr;
5966 int nbNodes=mesh->getNumberOfNodes();
5967 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5968 _num_nodes=renumArr;
5973 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5974 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5975 _num_faces=renumArr;
5979 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5982 renumArr->incrRef();
5986 * Sets the optional names of mesh entities of a given dimension.
5987 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5988 * \param [in] nameArr - the array of the names.
5989 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5990 * \throw If \a nameArr has an invalid size.
5992 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5994 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5996 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5997 switch(meshDimRelToMaxExt)
6001 int nbCells=mesh->getNumberOfCells();
6002 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
6003 _names_cells=nameArr;
6008 int nbNodes=mesh->getNumberOfNodes();
6009 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
6010 _names_nodes=nameArr;
6015 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6016 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
6017 _names_faces=nameArr;
6020 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6026 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
6028 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
6032 * Adds a group of nodes to \a this mesh.
6033 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
6034 * The ids should be sorted and different each other (MED file norm).
6036 * \warning this method can alter default "FAMILLE_ZERO" family.
6037 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6039 * \throw If the node coordinates array is not set.
6040 * \throw If \a ids == \c NULL.
6041 * \throw If \a ids->getName() == "".
6042 * \throw If \a ids does not respect the MED file norm.
6043 * \throw If a group with name \a ids->getName() already exists.
6045 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
6051 * Adds a group of nodes/cells/faces/edges to \a this mesh.
6053 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
6054 * The ids should be sorted and different each other (MED file norm).
6056 * \warning this method can alter default "FAMILLE_ZERO" family.
6057 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6059 * \throw If the node coordinates array is not set.
6060 * \throw If \a ids == \c NULL.
6061 * \throw If \a ids->getName() == "".
6062 * \throw If \a ids does not respect the MED file norm.
6063 * \throw If a group with name \a ids->getName() already exists.
6065 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
6067 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
6068 addGroupUnderground(false,ids,fam);
6073 * Returns the family field for mesh entities of a given dimension.
6074 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6075 * \return const DataArrayInt * - the family field. It is an array of ids of families
6076 * each mesh entity belongs to. It can be \c NULL.
6077 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6079 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
6081 switch(meshDimRelToMaxExt)
6090 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6095 * Returns the family field for mesh entities of a given dimension.
6096 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6097 * \return const DataArrayInt * - the family field. It is an array of ids of families
6098 * each mesh entity belongs to. It can be \c NULL.
6099 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6101 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
6103 switch(meshDimRelToMaxExt)
6112 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6117 * Returns the optional numbers of mesh entities of a given dimension.
6118 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6119 * \return const DataArrayInt * - the array of the entity numbers.
6120 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6121 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6123 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
6125 switch(meshDimRelToMaxExt)
6134 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6139 * Returns the optional numbers of mesh entities of a given dimension transformed using
6140 * DataArrayInt::invertArrayN2O2O2N().
6141 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6142 * \return const DataArrayInt * - the array of the entity numbers transformed using
6143 * DataArrayInt::invertArrayN2O2O2N().
6144 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6145 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6147 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
6149 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
6150 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
6151 if(meshDimRelToMaxExt==0)
6153 if((const DataArrayInt *)_num_cells)
6156 int maxValue=_num_cells->getMaxValue(pos);
6157 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
6158 return _rev_num_cells;
6161 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
6165 if((const DataArrayInt *)_num_nodes)
6168 int maxValue=_num_nodes->getMaxValue(pos);
6169 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
6170 return _rev_num_nodes;
6173 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6177 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6179 switch(meshDimRelToMaxExt)
6182 return _names_cells;
6184 return _names_nodes;
6186 return _names_faces;
6188 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6192 MCAuto<DataArrayInt> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6194 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6198 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6199 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6201 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6203 std::vector<int> ret(1);
6208 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6209 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6211 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6213 std::vector<int> ret(2);
6219 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6221 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6223 std::vector<int> ret;
6224 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6235 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6237 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6239 std::vector<int> ret;
6240 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6251 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6253 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6255 std::vector<int> ret;
6256 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6267 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6269 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
6271 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6275 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
6277 DataArrayInt *arr=_fam_nodes;
6279 arr->changeValue(oldId,newId);
6282 arr->changeValue(oldId,newId);
6285 arr->changeValue(oldId,newId);
6288 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6290 std::list< MCAuto<DataArrayInt> > ret;
6291 const DataArrayInt *da(_fam_nodes);
6293 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6296 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6299 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6303 void MEDFileStructuredMesh::deepCpyAttributes()
6305 if((const DataArrayInt*)_fam_nodes)
6306 _fam_nodes=_fam_nodes->deepCopy();
6307 if((const DataArrayInt*)_num_nodes)
6308 _num_nodes=_num_nodes->deepCopy();
6309 if((const DataArrayAsciiChar*)_names_nodes)
6310 _names_nodes=_names_nodes->deepCopy();
6311 if((const DataArrayInt*)_fam_cells)
6312 _fam_cells=_fam_cells->deepCopy();
6313 if((const DataArrayInt*)_num_cells)
6314 _num_cells=_num_cells->deepCopy();
6315 if((const DataArrayAsciiChar*)_names_cells)
6316 _names_cells=_names_cells->deepCopy();
6317 if((const DataArrayInt*)_fam_faces)
6318 _fam_faces=_fam_faces->deepCopy();
6319 if((const DataArrayInt*)_num_faces)
6320 _num_faces=_num_faces->deepCopy();
6321 if((const DataArrayAsciiChar*)_names_faces)
6322 _names_faces=_names_faces->deepCopy();
6323 if((const DataArrayInt*)_rev_num_nodes)
6324 _rev_num_nodes=_rev_num_nodes->deepCopy();
6325 if((const DataArrayInt*)_rev_num_cells)
6326 _rev_num_cells=_rev_num_cells->deepCopy();
6330 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6332 * \return a pointer to cartesian mesh that need to be managed by the caller.
6333 * \warning the returned pointer has to be managed by the caller.
6337 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6338 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6339 * \param [in] renum - it must be \c false.
6340 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6341 * delete using decrRef() as it is no more needed.
6343 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6347 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6348 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6349 switch(meshDimRelToMax)
6355 return const_cast<MEDCouplingStructuredMesh *>(m);
6360 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6361 buildMinusOneImplicitPartIfNeeded();
6362 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6368 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6372 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6374 std::vector<int> ret;
6375 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6376 if(famCells && famCells->presenceOfValue(ret))
6378 if(famFaces && famFaces->presenceOfValue(ret))
6383 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6385 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6386 const DataArrayInt *famNodes(_fam_nodes);
6387 if(famNodes && famNodes->presenceOfValue(ret))
6393 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6394 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6395 * \return int - the number of entities.
6396 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6398 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6400 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6402 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6403 switch(meshDimRelToMaxExt)
6406 return cmesh->getNumberOfCells();
6408 return cmesh->getNumberOfNodes();
6410 return cmesh->getNumberOfCellsOfSubLevelMesh();
6412 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6416 int MEDFileStructuredMesh::getNumberOfNodes() const
6418 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6420 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6421 return cmesh->getNumberOfNodes();
6424 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6426 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6428 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6429 switch(meshDimRelToMaxExt)
6432 return cmesh->getNumberOfCells();
6434 return cmesh->getNumberOfCellsOfSubLevelMesh();
6436 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6440 bool MEDFileStructuredMesh::hasImplicitPart() const
6446 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6448 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6450 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6451 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6454 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6455 if(cm.getReverseExtrudedType()!=gt)
6456 throw INTERP_KERNEL::Exception(MSG);
6457 buildImplicitPart();
6458 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6462 if(gt!=zeFaceMesh->getCellModelEnum())
6463 throw INTERP_KERNEL::Exception(MSG);
6464 return zeFaceMesh->getNumberOfCells();
6468 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6470 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6472 buildImplicitPart();
6475 void MEDFileStructuredMesh::buildImplicitPart() const
6477 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6479 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6480 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6483 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6485 _faces_if_necessary=0;
6489 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6490 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6492 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6494 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6497 return _faces_if_necessary;
6500 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6502 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6504 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6505 switch(meshDimRelToMax)
6509 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6514 int mdim(cmesh->getMeshDimension());
6516 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6517 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6521 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6525 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6527 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6530 return getNumberOfCellsAtLevel(0);
6533 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6535 if(st.getNumberOfItems()!=1)
6536 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 !");
6537 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6538 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6539 if(getNumberOfNodes()!=(int)nodesFetched.size())
6540 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6541 if(st[0].getPflName().empty())
6543 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6546 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6547 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6548 int sz(nodesFetched.size());
6549 for(const int *work=arr->begin();work!=arr->end();work++)
6551 std::vector<int> conn;
6552 cmesh->getNodeIdsOfCell(*work,conn);
6553 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6554 if(*it>=0 && *it<sz)
6555 nodesFetched[*it]=true;
6557 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6561 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6563 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6567 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6568 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6570 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6571 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6573 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6576 if(!mrs || mrs->isCellFamilyFieldReading())
6578 famCells=DataArrayInt::New();
6579 famCells->alloc(nbOfElt,1);
6580 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6583 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6586 if(!mrs || mrs->isCellNumFieldReading())
6588 numCells=DataArrayInt::New();
6589 numCells->alloc(nbOfElt,1);
6590 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6593 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6596 if(!mrs || mrs->isCellNameFieldReading())
6598 namesCells=DataArrayAsciiChar::New();
6599 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6600 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6601 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6606 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6608 setName(strm->getName());
6609 setDescription(strm->getDescription());
6610 setUnivName(strm->getUnivName());
6611 setIteration(strm->getIteration());
6612 setOrder(strm->getOrder());
6613 setTimeValue(strm->getTime());
6614 setTimeUnit(strm->getTimeUnit());
6615 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6616 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6617 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6620 if(!mrs || mrs->isNodeFamilyFieldReading())
6622 int nbNodes(getNumberOfNodes());
6624 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6625 _fam_nodes=DataArrayInt::New();
6626 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6627 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...
6628 _fam_nodes->fillWithZero();
6629 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6632 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6635 if(!mrs || mrs->isNodeNumFieldReading())
6637 _num_nodes=DataArrayInt::New();
6638 _num_nodes->alloc(nbOfElt,1);
6639 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6642 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6645 if(!mrs || mrs->isNodeNameFieldReading())
6647 _names_nodes=DataArrayAsciiChar::New();
6648 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6649 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6650 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6653 int meshDim(getStructuredMesh()->getMeshDimension());
6654 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6656 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6659 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6661 int meshDim(getStructuredMesh()->getMeshDimension());
6662 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6664 if((const DataArrayInt *)_fam_cells)
6665 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6666 if((const DataArrayInt *)_fam_faces)
6667 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6668 if((const DataArrayInt *)_fam_nodes)
6669 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6670 if((const DataArrayInt *)_num_cells)
6671 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6672 if((const DataArrayInt *)_num_faces)
6673 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6674 if((const DataArrayInt *)_num_nodes)
6675 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6676 if((const DataArrayAsciiChar *)_names_cells)
6678 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6680 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6681 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6682 throw INTERP_KERNEL::Exception(oss.str().c_str());
6684 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6686 if((const DataArrayAsciiChar *)_names_faces)
6688 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6690 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6691 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6692 throw INTERP_KERNEL::Exception(oss.str().c_str());
6694 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6696 if((const DataArrayAsciiChar *)_names_nodes)
6698 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6700 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6701 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6702 throw INTERP_KERNEL::Exception(oss.str().c_str());
6704 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6707 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6711 * Returns an empty instance of MEDFileCMesh.
6712 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6713 * mesh using decrRef() as it is no more needed.
6715 MEDFileCMesh *MEDFileCMesh::New()
6717 return new MEDFileCMesh;
6721 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6722 * file. The first mesh in the file is loaded.
6723 * \param [in] fileName - the name of MED file to read.
6724 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6725 * mesh using decrRef() as it is no more needed.
6726 * \throw If the file is not readable.
6727 * \throw If there is no meshes in the file.
6728 * \throw If the mesh in the file is not a Cartesian one.
6730 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6732 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6733 return New(fid,mrs);
6736 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6738 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6742 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6743 * file. The mesh to load is specified by its name and numbers of a time step and an
6745 * \param [in] fileName - the name of MED file to read.
6746 * \param [in] mName - the name of the mesh to read.
6747 * \param [in] dt - the number of a time step.
6748 * \param [in] it - the number of an iteration.
6749 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6750 * mesh using decrRef() as it is no more needed.
6751 * \throw If the file is not readable.
6752 * \throw If there is no mesh with given attributes in the file.
6753 * \throw If the mesh in the file is not a Cartesian one.
6755 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6757 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6758 return New(fid,mName,dt,it,mrs);
6761 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6763 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6766 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6768 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6771 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6773 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6774 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6779 * Returns the dimension on cells in \a this mesh.
6780 * \return int - the mesh dimension.
6781 * \throw If there are no cells in this mesh.
6783 int MEDFileCMesh::getMeshDimension() const
6785 if(!((const MEDCouplingCMesh*)_cmesh))
6786 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6787 return _cmesh->getMeshDimension();
6791 * Returns the dimension on nodes in \a this mesh.
6792 * \return int - the space dimension.
6793 * \throw If there are no cells in this mesh.
6795 int MEDFileCMesh::getSpaceDimension() const
6797 if(!((const MEDCouplingCMesh*)_cmesh))
6798 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6799 return _cmesh->getSpaceDimension();
6803 * Returns a string describing \a this mesh.
6804 * \return std::string - the mesh information string.
6806 std::string MEDFileCMesh::simpleRepr() const
6808 return MEDFileStructuredMesh::simpleRepr();
6812 * Returns a full textual description of \a this mesh.
6813 * \return std::string - the string holding the mesh description.
6815 std::string MEDFileCMesh::advancedRepr() const
6817 return simpleRepr();
6820 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6822 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6826 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6828 return new MEDFileCMesh;
6831 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6833 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6834 ret->deepCpyEquivalences(*this);
6835 if((const MEDCouplingCMesh*)_cmesh)
6836 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6837 ret->deepCpyAttributes();
6842 * Checks if \a this and another mesh are equal.
6843 * \param [in] other - the mesh to compare with.
6844 * \param [in] eps - a precision used to compare real values.
6845 * \param [in,out] what - the string returning description of unequal data.
6846 * \return bool - \c true if the meshes are equal, \c false, else.
6848 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6850 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6852 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6855 what="Mesh types differ ! This is cartesian and other is NOT !";
6858 clearNonDiscrAttributes();
6859 otherC->clearNonDiscrAttributes();
6860 const MEDCouplingCMesh *coo1=_cmesh;
6861 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6862 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6864 what="Mismatch of cartesian meshes ! One is defined and not other !";
6869 bool ret=coo1->isEqual(coo2,eps);
6872 what="cartesian meshes differ !";
6880 * Clears redundant attributes of incorporated data arrays.
6882 void MEDFileCMesh::clearNonDiscrAttributes() const
6884 MEDFileStructuredMesh::clearNonDiscrAttributes();
6885 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6888 MEDFileCMesh::MEDFileCMesh()
6892 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6895 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6897 catch(INTERP_KERNEL::Exception& e)
6902 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6904 MEDCoupling::MEDCouplingMeshType meshType;
6907 MEDCoupling::MEDCouplingAxisType axType;
6908 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6909 if(meshType!=CARTESIAN)
6911 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6912 throw INTERP_KERNEL::Exception(oss.str().c_str());
6914 MEDFileCMeshL2 loaderl2;
6915 loaderl2.loadAll(fid,mid,mName,dt,it);
6916 setAxisType(axType);
6917 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6920 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6924 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6925 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6927 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6929 synchronizeTinyInfoOnLeaves();
6933 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6935 synchronizeTinyInfoOnLeaves();
6940 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6941 * \param [in] m - the new MEDCouplingCMesh to refer to.
6942 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6945 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6947 dealWithTinyInfo(m);
6953 MEDFileMesh *MEDFileCMesh::cartesianize() const
6955 if(getAxisType()==AX_CART)
6958 return const_cast<MEDFileCMesh *>(this);
6962 const MEDCouplingCMesh *cmesh(getMesh());
6964 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6965 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6966 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6967 clmesh->setCoords(coords);
6968 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6969 ret->MEDFileStructuredMesh::operator=(*this);
6970 ret->setMesh(clmesh);
6971 ret->setAxisType(AX_CART);
6976 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6978 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6979 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6980 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6981 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6982 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6983 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6984 int spaceDim(_cmesh->getSpaceDimension());
6985 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6986 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6987 for(int i=0;i<spaceDim;i++)
6989 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
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,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6997 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6998 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6999 for(int i=0;i<spaceDim;i++)
7001 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
7002 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
7005 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7006 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7009 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
7011 const MEDCouplingCMesh *cmesh=_cmesh;
7014 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
7015 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
7016 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
7017 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
7020 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
7022 return new MEDFileCurveLinearMesh;
7025 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
7027 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
7030 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
7032 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7033 return New(fid,mrs);
7036 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7038 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7039 return New(fid,mName,dt,it,mrs);
7042 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7044 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
7047 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
7049 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
7052 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
7054 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
7055 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
7059 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
7061 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7065 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
7067 return new MEDFileCurveLinearMesh;
7070 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
7072 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7073 ret->deepCpyEquivalences(*this);
7074 if((const MEDCouplingCurveLinearMesh*)_clmesh)
7075 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
7076 ret->deepCpyAttributes();
7080 int MEDFileCurveLinearMesh::getMeshDimension() const
7082 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7083 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
7084 return _clmesh->getMeshDimension();
7087 std::string MEDFileCurveLinearMesh::simpleRepr() const
7089 return MEDFileStructuredMesh::simpleRepr();
7092 std::string MEDFileCurveLinearMesh::advancedRepr() const
7094 return simpleRepr();
7097 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7099 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7101 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
7104 what="Mesh types differ ! This is curve linear and other is NOT !";
7107 clearNonDiscrAttributes();
7108 otherC->clearNonDiscrAttributes();
7109 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
7110 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
7111 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7113 what="Mismatch of curve linear meshes ! One is defined and not other !";
7118 bool ret=coo1->isEqual(coo2,eps);
7121 what="curve linear meshes differ !";
7128 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
7130 MEDFileStructuredMesh::clearNonDiscrAttributes();
7131 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
7134 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
7136 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
7139 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
7140 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
7141 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
7142 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
7145 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
7147 synchronizeTinyInfoOnLeaves();
7151 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
7153 dealWithTinyInfo(m);
7159 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
7161 if(getAxisType()==AX_CART)
7164 return const_cast<MEDFileCurveLinearMesh *>(this);
7168 const MEDCouplingCurveLinearMesh *mesh(getMesh());
7170 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7171 const DataArrayDouble *coords(mesh->getCoords());
7173 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
7174 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7175 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
7176 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7177 mesh2->setCoords(coordsCart);
7178 ret->setMesh(mesh2);
7179 ret->setAxisType(AX_CART);
7184 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7186 synchronizeTinyInfoOnLeaves();
7190 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7194 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7197 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7199 catch(INTERP_KERNEL::Exception& e)
7204 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7206 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7207 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7208 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7209 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7210 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7211 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7212 int spaceDim=_clmesh->getSpaceDimension();
7213 int meshDim=_clmesh->getMeshDimension();
7214 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7215 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7216 const DataArrayDouble *coords=_clmesh->getCoords();
7218 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7219 for(int i=0;i<spaceDim;i++)
7221 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7223 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7224 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
7225 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
7227 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7229 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7230 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7231 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
7232 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
7234 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
7236 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7237 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7240 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7242 MEDCoupling::MEDCouplingMeshType meshType;
7245 MEDCoupling::MEDCouplingAxisType axType;
7246 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7247 setAxisType(axType);
7248 if(meshType!=CURVE_LINEAR)
7250 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7251 throw INTERP_KERNEL::Exception(oss.str().c_str());
7253 MEDFileCLMeshL2 loaderl2;
7254 loaderl2.loadAll(fid,mid,mName,dt,it);
7255 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7258 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7261 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7263 return new MEDFileMeshMultiTS;
7266 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7268 return new MEDFileMeshMultiTS(fid);
7271 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7273 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7277 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7279 return new MEDFileMeshMultiTS(fid,mName);
7282 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7284 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7285 return New(fid,mName);
7288 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7290 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7291 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7293 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7294 if((const MEDFileMesh *)*it)
7295 meshOneTs[i]=(*it)->deepCopy();
7296 ret->_mesh_one_ts=meshOneTs;
7300 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7302 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7305 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7307 std::vector<const BigMemoryObject *> ret;
7308 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7309 ret.push_back((const MEDFileMesh *)*it);
7313 std::string MEDFileMeshMultiTS::getName() const
7315 if(_mesh_one_ts.empty())
7316 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7317 return _mesh_one_ts[0]->getName();
7320 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7322 std::string oldName(getName());
7323 std::vector< std::pair<std::string,std::string> > v(1);
7324 v[0].first=oldName; v[0].second=newMeshName;
7328 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7331 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7333 MEDFileMesh *cur(*it);
7335 ret=cur->changeNames(modifTab) || ret;
7340 void MEDFileMeshMultiTS::cartesianizeMe()
7342 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7344 MEDFileMesh *cur(*it);
7347 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7353 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7355 if(_mesh_one_ts.empty())
7356 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7357 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7360 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7363 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7364 _mesh_one_ts.resize(1);
7365 mesh1TimeStep->incrRef();
7366 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7367 _mesh_one_ts[0]=mesh1TimeStep;
7370 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7372 if ( MEDFileMesh* m = getOneTimeStep() )
7373 return m->getJoints();
7378 * \brief Set Joints that are common to all time-stamps
7380 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7382 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7384 (*it)->setJoints( joints );
7388 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7390 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7391 if((*it).isNotNull())
7392 if((*it)->presenceOfStructureElements())
7397 void MEDFileMeshMultiTS::killStructureElements()
7399 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7400 if((*it).isNotNull())
7401 (*it)->killStructureElements();
7404 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7406 MEDFileJoints *joints(getJoints());
7407 bool jointsWritten(false);
7409 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7411 if ( jointsWritten )
7412 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7414 jointsWritten = true;
7416 (*it)->copyOptionsFrom(*this);
7417 (*it)->writeLL(fid);
7420 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7423 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7425 MEDFileJoints *joints(0);
7426 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7428 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7429 joints = getOneTimeStep()->getJoints();
7431 _mesh_one_ts.clear(); //for the moment to be improved
7432 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7435 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7439 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7442 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7445 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7446 throw INTERP_KERNEL::Exception(oss.str().c_str());
7449 MEDCoupling::MEDCouplingMeshType meshType;
7451 MEDCoupling::MEDCouplingAxisType dummy3;
7452 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7453 loadFromFile(fid,ms.front());
7455 catch(INTERP_KERNEL::Exception& e)
7460 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7463 loadFromFile(fid,mName);
7465 catch(INTERP_KERNEL::Exception& e)
7470 MEDFileMeshes *MEDFileMeshes::New()
7472 return new MEDFileMeshes;
7475 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7477 return new MEDFileMeshes(fid);
7480 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7482 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7486 void MEDFileMeshes::writeLL(med_idt fid) const
7488 checkConsistencyLight();
7489 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7491 (*it)->copyOptionsFrom(*this);
7492 (*it)->writeLL(fid);
7496 // MEDFileMeshes::writ checkConsistencyLight();
7498 int MEDFileMeshes::getNumberOfMeshes() const
7500 return _meshes.size();
7503 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7505 return new MEDFileMeshesIterator(this);
7508 /** Return a borrowed reference (caller is not responsible) */
7509 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7511 if(i<0 || i>=(int)_meshes.size())
7513 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7514 throw INTERP_KERNEL::Exception(oss.str().c_str());
7516 return _meshes[i]->getOneTimeStep();
7519 /** Return a borrowed reference (caller is not responsible) */
7520 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7522 std::vector<std::string> ms=getMeshesNames();
7523 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7526 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7527 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7528 throw INTERP_KERNEL::Exception(oss.str().c_str());
7530 return getMeshAtPos((int)std::distance(ms.begin(),it));
7533 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7535 std::vector<std::string> ret(_meshes.size());
7537 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7539 const MEDFileMeshMultiTS *f=(*it);
7542 ret[i]=f->getName();
7546 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7547 throw INTERP_KERNEL::Exception(oss.str().c_str());
7553 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7556 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7558 MEDFileMeshMultiTS *cur(*it);
7560 ret=cur->changeNames(modifTab) || ret;
7565 void MEDFileMeshes::cartesianizeMe()
7567 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7569 MEDFileMeshMultiTS *cur(*it);
7571 cur->cartesianizeMe();
7575 void MEDFileMeshes::resize(int newSize)
7577 _meshes.resize(newSize);
7580 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7583 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7584 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7585 elt->setOneTimeStep(mesh);
7586 _meshes.push_back(elt);
7589 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7592 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7593 if(i>=(int)_meshes.size())
7594 _meshes.resize(i+1);
7595 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7596 elt->setOneTimeStep(mesh);
7600 void MEDFileMeshes::destroyMeshAtPos(int i)
7602 if(i<0 || i>=(int)_meshes.size())
7604 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7605 throw INTERP_KERNEL::Exception(oss.str().c_str());
7607 _meshes.erase(_meshes.begin()+i);
7610 void MEDFileMeshes::loadFromFile(med_idt fid)
7612 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7614 _meshes.resize(ms.size());
7615 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7616 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7619 MEDFileMeshes::MEDFileMeshes()
7623 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7628 catch(INTERP_KERNEL::Exception& /*e*/)
7632 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7634 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7636 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7637 if((const MEDFileMeshMultiTS *)*it)
7638 meshes[i]=(*it)->deepCopy();
7639 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7640 ret->_meshes=meshes;
7644 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7646 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7649 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7651 std::vector<const BigMemoryObject *> ret;
7652 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7653 ret.push_back((const MEDFileMeshMultiTS *)*it);
7657 std::string MEDFileMeshes::simpleRepr() const
7659 std::ostringstream oss;
7660 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7661 simpleReprWithoutHeader(oss);
7665 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7667 int nbOfMeshes=getNumberOfMeshes();
7668 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7669 std::vector<std::string> mns=getMeshesNames();
7670 for(int i=0;i<nbOfMeshes;i++)
7671 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7674 void MEDFileMeshes::checkConsistencyLight() const
7676 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7678 std::set<std::string> s;
7679 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7681 const MEDFileMeshMultiTS *elt=(*it);
7684 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7685 throw INTERP_KERNEL::Exception(oss.str().c_str());
7687 std::size_t sz=s.size();
7688 s.insert(std::string((*it)->getName()));
7691 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7692 throw INTERP_KERNEL::Exception(oss.str().c_str());
7697 bool MEDFileMeshes::presenceOfStructureElements() const
7699 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7700 if((*it).isNotNull())
7701 if((*it)->presenceOfStructureElements())
7706 void MEDFileMeshes::killStructureElements()
7708 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7709 if((*it).isNotNull())
7710 (*it)->killStructureElements();
7713 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7718 _nb_iter=ms->getNumberOfMeshes();
7722 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7726 MEDFileMesh *MEDFileMeshesIterator::nextt()
7728 if(_iter_id<_nb_iter)
7730 MEDFileMeshes *ms(_ms);
7732 return ms->getMeshAtPos(_iter_id++);
7740 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7742 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7743 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7745 if(geoType==MED_NO_GEOTYPE)
7746 return INTERP_KERNEL::NORM_ERROR;
7747 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7748 throw INTERP_KERNEL::Exception(oss.str());
7750 return typmai2[std::distance(typmai,pos)];
7753 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7763 std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7764 throw INTERP_KERNEL::Exception(oss.str());