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.
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.
811 void MEDFileMesh::removeFamiliesReferedByNoGroups()
813 std::map<std::string,int> fams;
814 std::set<std::string> sfams;
815 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
816 sfams.insert((*it).first);
817 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
818 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
820 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
821 if(*it!=DFT_FAM_NAME)
822 _families.erase(*it);
826 * 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
827 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
828 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
830 * 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.
832 * \sa MEDFileMesh::removeOrphanFamilies
834 void MEDFileMesh::rearrangeFamilies()
836 checkOrphanFamilyZero();
837 removeFamiliesReferedByNoGroups();
839 std::vector<int> levels(getNonEmptyLevelsExt());
840 std::set<int> idsRefed;
841 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
843 idsRefed.insert((*it).second);
846 if(!getGroupsOnFamily((*it).first).empty())
848 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 !";
849 throw INTERP_KERNEL::Exception(oss.str());
853 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
855 const DataArrayInt *fams(0);
858 fams=getFamilyFieldAtLevel(*it);
860 catch(INTERP_KERNEL::Exception& e) { }
863 std::vector<bool> v(fams->getNumberOfTuples(),false);
864 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
865 fams->switchOnTupleEqualTo(*pt,v);
866 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
867 if(!unfetchedIds->empty())
869 MCAuto<DataArrayInt> newFams(fams->deepCopy());
870 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
871 setFamilyFieldArr(*it,newFams);
874 removeOrphanFamilies();
878 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
880 void MEDFileMesh::checkOrphanFamilyZero() const
882 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
884 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
886 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
887 throw INTERP_KERNEL::Exception(oss.str().c_str());
893 * Renames a group in \a this mesh.
894 * \param [in] oldName - a current name of the group to rename.
895 * \param [in] newName - a new group name.
896 * \throw If no group named \a oldName exists in \a this mesh.
897 * \throw If a group named \a newName already exists.
899 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
901 std::string oname(oldName);
902 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
903 std::vector<std::string> grps=getGroupsNames();
904 if(it==_groups.end())
906 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
907 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
908 throw INTERP_KERNEL::Exception(oss.str().c_str());
910 std::string nname(newName);
911 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
912 if(it2!=_groups.end())
914 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
915 throw INTERP_KERNEL::Exception(oss.str().c_str());
917 std::vector<std::string> cpy=(*it).second;
919 _groups[newName]=cpy;
923 * Changes an id of a family in \a this mesh.
924 * This method calls changeFamilyIdArr().
925 * \param [in] oldId - a current id of the family.
926 * \param [in] newId - a new family id.
928 void MEDFileMesh::changeFamilyId(int oldId, int newId)
930 changeFamilyIdArr(oldId,newId);
931 std::map<std::string,int> fam2;
932 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
934 if((*it).second==oldId)
935 fam2[(*it).first]=newId;
937 fam2[(*it).first]=(*it).second;
943 * Renames a family in \a this mesh.
944 * \param [in] oldName - a current name of the family to rename.
945 * \param [in] newName - a new family name.
946 * \throw If no family named \a oldName exists in \a this mesh.
947 * \throw If a family named \a newName already exists.
949 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
951 std::string oname(oldName);
952 std::map<std::string, int >::iterator it=_families.find(oname);
953 std::vector<std::string> fams=getFamiliesNames();
954 if(it==_families.end())
956 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
957 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
958 throw INTERP_KERNEL::Exception(oss.str().c_str());
960 std::string nname(newName);
961 std::map<std::string, int >::iterator it2=_families.find(nname);
962 if(it2!=_families.end())
964 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
965 throw INTERP_KERNEL::Exception(oss.str().c_str());
967 int cpy=(*it).second;
969 _families[newName]=cpy;
970 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
972 std::vector<std::string>& v=(*it3).second;
973 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
980 * Checks if \a this and another mesh contains the same families.
981 * \param [in] other - the mesh to compare with \a this one.
982 * \param [in,out] what - an unused parameter.
983 * \return bool - \c true if number of families and their ids are the same in the two
984 * meshes. Families with the id == \c 0 are not considered.
986 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
988 if(_families==other->_families)
990 std::map<std::string,int> fam0;
991 std::map<std::string,int> fam1;
992 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
994 fam0[(*it).first]=(*it).second;
995 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
997 fam1[(*it).first]=(*it).second;
1002 * Checks if \a this and another mesh contains the same groups.
1003 * \param [in] other - the mesh to compare with \a this one.
1004 * \param [in,out] what - a string describing a difference of groups of the two meshes
1005 * in case if this method returns \c false.
1006 * \return bool - \c true if number of groups and families constituting them are the
1007 * same in the two meshes.
1009 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
1011 if(_groups==other->_groups)
1014 std::size_t sz=_groups.size();
1015 if(sz!=other->_groups.size())
1017 what="Groups differ because not same number !\n";
1022 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
1023 for(std::size_t i=0;i<sz && ret;i++,it1++)
1025 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
1026 if(it2!=other->_groups.end())
1028 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
1029 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1035 what="A group in first mesh exists not in other !\n";
1041 std::ostringstream oss; oss << "Groups description differs :\n";
1042 oss << "First group description :\n";
1043 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1045 oss << " Group \"" << (*it).first << "\" on following families :\n";
1046 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1047 oss << " \"" << *it2 << "\n";
1049 oss << "Second group description :\n";
1050 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1052 oss << " Group \"" << (*it).first << "\" on following families :\n";
1053 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1054 oss << " \"" << *it2 << "\n";
1062 * Checks if a group with a given name exists in \a this mesh.
1063 * \param [in] groupName - the group name.
1064 * \return bool - \c true the group \a groupName exists in \a this mesh.
1066 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1068 std::string grpName(groupName);
1069 return _groups.find(grpName)!=_groups.end();
1073 * Checks if a family with a given id exists in \a this mesh.
1074 * \param [in] famId - the family id.
1075 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1077 bool MEDFileMesh::existsFamily(int famId) const
1079 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1080 if((*it2).second==famId)
1086 * Checks if a family with a given name exists in \a this mesh.
1087 * \param [in] familyName - the family name.
1088 * \return bool - \c true the family \a familyName exists in \a this mesh.
1090 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1092 std::string fname(familyName);
1093 return _families.find(fname)!=_families.end();
1097 * Sets an id of a family.
1098 * \param [in] familyName - the family name.
1099 * \param [in] id - a new id of the family.
1101 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1103 std::string fname(familyName);
1104 _families[fname]=id;
1107 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1109 std::string fname(familyName);
1110 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1111 if((*it).second==id)
1113 if((*it).first!=familyName)
1115 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1116 throw INTERP_KERNEL::Exception(oss.str().c_str());
1119 _families[fname]=id;
1123 * Adds a family to \a this mesh.
1124 * \param [in] familyName - a name of the family.
1125 * \param [in] famId - an id of the family.
1126 * \throw If a family with the same name or id already exists in \a this mesh.
1128 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1130 std::string fname(familyName);
1131 std::map<std::string,int>::const_iterator it=_families.find(fname);
1132 if(it==_families.end())
1134 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1135 if((*it2).second==famId)
1137 std::ostringstream oss;
1138 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1139 throw INTERP_KERNEL::Exception(oss.str().c_str());
1141 _families[fname]=famId;
1145 if((*it).second!=famId)
1147 std::ostringstream oss;
1148 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1149 throw INTERP_KERNEL::Exception(oss.str().c_str());
1155 * Creates a group including all mesh entities of given dimension.
1156 * \warning This method does \b not guarantee that the created group includes mesh
1157 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1158 * present in family fields of different dimensions. To assure this, call
1159 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1160 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1162 * \param [in] groupName - a name of the new group.
1163 * \throw If a group named \a groupName already exists.
1164 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1165 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1167 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1169 std::string grpName(groupName);
1170 std::vector<int> levs=getNonEmptyLevelsExt();
1171 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1173 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1174 oss << "Available relative ext levels are : ";
1175 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1176 throw INTERP_KERNEL::Exception(oss.str().c_str());
1178 if(existsGroup(groupName))
1180 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1181 oss << "Already existing groups are : ";
1182 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1183 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1184 throw INTERP_KERNEL::Exception(oss.str().c_str());
1186 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1188 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1189 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1190 std::vector<std::string> familiesOnWholeGroup;
1191 for(const int *it=famIds->begin();it!=famIds->end();it++)
1194 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1196 _groups[grpName]=familiesOnWholeGroup;
1200 * Ensures that given family ids do not present in family fields of dimensions different
1201 * than given ones. If a family id is present in the family fields of dimensions different
1202 * than the given ones, a new family is created and the whole data is updated accordingly.
1203 * \param [in] famIds - a sequence of family ids to check.
1204 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1205 * famIds should exclusively belong.
1206 * \return bool - \c true if no modification is done in \a this mesh by this method.
1208 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1210 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1211 std::vector<int> levs=getNonEmptyLevelsExt();
1212 std::set<int> levs2(levs.begin(),levs.end());
1213 std::vector<int> levsToTest;
1214 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1215 std::set<int> famIds2(famIds.begin(),famIds.end());
1218 if(!_families.empty())
1219 maxFamId=getMaxFamilyId()+1;
1220 std::vector<std::string> allFams=getFamiliesNames();
1221 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1223 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1226 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1227 std::vector<int> tmp;
1228 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1229 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1232 std::string famName=getFamilyNameGivenId(*it2);
1233 std::ostringstream oss; oss << "Family_" << maxFamId;
1234 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1235 addFamilyOnAllGroupsHaving(famName,zeName);
1236 _families[zeName]=maxFamId;
1237 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1246 * Adds a family to a given group in \a this mesh. If the group with a given name does
1247 * not exist, it is created.
1248 * \param [in] grpName - the name of the group to add the family in.
1249 * \param [in] famName - the name of the family to add to the group named \a grpName.
1250 * \throw If \a grpName or \a famName is an empty string.
1251 * \throw If no family named \a famName is present in \a this mesh.
1253 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1255 std::string grpn(grpName);
1256 std::string famn(famName);
1257 if(grpn.empty() || famn.empty())
1258 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1259 std::vector<std::string> fams=getFamiliesNames();
1260 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1262 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1263 oss << "Create this family or choose an existing one ! Existing fams are : ";
1264 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1265 throw INTERP_KERNEL::Exception(oss.str().c_str());
1267 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1268 if(it==_groups.end())
1270 _groups[grpn].push_back(famn);
1274 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1275 if(it2==(*it).second.end())
1276 (*it).second.push_back(famn);
1281 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1282 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1283 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1285 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1287 std::string famNameCpp(famName);
1288 std::string otherCpp(otherFamName);
1289 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1291 std::vector<std::string>& v=(*it).second;
1292 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1294 v.push_back(otherCpp);
1299 void MEDFileMesh::checkNoGroupClash(const DataArrayInt *famArr, const std::string& grpName) const
1301 std::vector<std::string> grpsNames(getGroupsNames());
1302 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
1304 std::vector<int> famIds(getFamiliesIdsOnGroup(grpName));
1305 if(famArr->presenceOfValue(famIds))
1307 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
1308 throw INTERP_KERNEL::Exception(oss.str().c_str());
1313 * \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).
1314 * \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)
1316 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1319 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1320 std::string grpName(ids->getName());
1322 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1323 ids->checkStrictlyMonotonic(true);
1324 checkNoGroupClash(famArr,grpName);
1325 MCAuto<DataArrayInt> famArrTmp; famArrTmp.takeRef(famArr);
1326 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1327 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1328 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1329 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1330 std::vector<int> familyIds;
1331 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1332 int maxVal=getTheMaxAbsFamilyId()+1;
1333 std::map<std::string,int> families(_families);
1334 std::map<std::string, std::vector<std::string> > groups(_groups);
1335 std::vector<std::string> fams;
1336 bool created(false);
1337 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1339 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1340 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1341 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1342 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1345 bool isFamPresent=false;
1346 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1347 isFamPresent=(*itl)->presenceOfValue(*famId);
1348 if(!isFamPresent && *famId!=0)
1349 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1352 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1353 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1354 fams.push_back(locFamName);
1355 if(existsFamily(*famId))
1357 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1358 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1361 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1365 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1366 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1367 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1368 if(existsFamily(*famId))
1370 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1371 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1376 for(std::size_t i=0;i<familyIds.size();i++)
1378 DataArrayInt *da=idsPerfamiliyIds[i];
1379 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1382 std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
1383 if(itt!=groups.end())
1385 std::vector<std::string>& famsOnGrp((*itt).second);
1386 famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
1389 groups[grpName]=fams;
1393 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1395 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1398 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1400 std::string fam(familyNameToChange);
1401 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1403 std::vector<std::string>& fams((*it).second);
1404 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1408 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1414 * Returns a name of the family having a given id or, if no such a family exists, creates
1415 * a new uniquely named family and returns its name.
1416 * \param [in] id - the id of the family whose name is required.
1417 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1418 * \return std::string - the name of the existing or the created family.
1419 * \throw If it is not possible to create a unique family name.
1421 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1423 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1427 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1428 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1429 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1430 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1432 * This method will throws an exception if it is not possible to create a unique family name.
1434 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1436 std::vector<std::string> famAlreadyExisting(families.size());
1438 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1440 if((*it).second!=id)
1442 famAlreadyExisting[ii]=(*it).first;
1451 std::ostringstream oss; oss << "Family_" << id;
1452 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1458 * Sets names and ids of all families in \a this mesh.
1459 * \param [in] info - a map of a family name to a family id.
1461 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1467 * Sets names of all groups and families constituting them in \a this mesh.
1468 * \param [in] info - a map of a group name to a vector of names of families
1469 * constituting the group.
1471 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1477 * Returns an id of the family having a given name.
1478 * \param [in] name - the name of the family of interest.
1479 * \return int - the id of the family of interest.
1480 * \throw If no family with such a \a name exists.
1482 int MEDFileMesh::getFamilyId(const std::string& name) const
1484 std::map<std::string, int>::const_iterator it=_families.find(name);
1485 if(it==_families.end())
1487 std::vector<std::string> fams(getFamiliesNames());
1488 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1489 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1490 throw INTERP_KERNEL::Exception(oss.str().c_str());
1492 return (*it).second;
1496 * Returns ids of the families having given names.
1497 * \param [in] fams - a sequence of the names of families of interest.
1498 * \return std::vector<int> - a sequence of the ids of families of interest.
1499 * \throw If \a fams contains a name of an inexistent family.
1501 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1503 std::vector<int> ret(fams.size());
1505 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1507 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1508 if(it2==_families.end())
1510 std::vector<std::string> fams2=getFamiliesNames();
1511 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1512 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1513 throw INTERP_KERNEL::Exception(oss.str().c_str());
1515 ret[i]=(*it2).second;
1521 * Returns a maximal abs(id) of families in \a this mesh.
1522 * \return int - the maximal norm of family id.
1523 * \throw If there are no families in \a this mesh.
1525 int MEDFileMesh::getMaxAbsFamilyId() const
1527 if(_families.empty())
1528 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1529 int ret=-std::numeric_limits<int>::max();
1530 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1532 ret=std::max(std::abs((*it).second),ret);
1538 * Returns a maximal id of families in \a this mesh.
1539 * \return int - the maximal family id.
1540 * \throw If there are no families in \a this mesh.
1542 int MEDFileMesh::getMaxFamilyId() const
1544 if(_families.empty())
1545 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1546 int ret=-std::numeric_limits<int>::max();
1547 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1549 ret=std::max((*it).second,ret);
1555 * Returns a minimal id of families in \a this mesh.
1556 * \return int - the minimal family id.
1557 * \throw If there are no families in \a this mesh.
1559 int MEDFileMesh::getMinFamilyId() const
1561 if(_families.empty())
1562 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1563 int ret=std::numeric_limits<int>::max();
1564 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1566 ret=std::min((*it).second,ret);
1572 * Returns a maximal id of families in \a this mesh. Not only named families are
1573 * considered but all family fields as well.
1574 * \return int - the maximal family id.
1576 int MEDFileMesh::getTheMaxAbsFamilyId() const
1578 int m1=-std::numeric_limits<int>::max();
1579 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1580 m1=std::max(std::abs((*it).second),m1);
1581 int m2=getMaxAbsFamilyIdInArrays();
1582 return std::max(m1,m2);
1586 * Returns a maximal id of families in \a this mesh. Not only named families are
1587 * considered but all family fields as well.
1588 * \return int - the maximal family id.
1590 int MEDFileMesh::getTheMaxFamilyId() const
1592 int m1=-std::numeric_limits<int>::max();
1593 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1594 m1=std::max((*it).second,m1);
1595 int m2=getMaxFamilyIdInArrays();
1596 return std::max(m1,m2);
1600 * Returns a minimal id of families in \a this mesh. Not only named families are
1601 * considered but all family fields as well.
1602 * \return int - the minimal family id.
1604 int MEDFileMesh::getTheMinFamilyId() const
1606 int m1=std::numeric_limits<int>::max();
1607 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1608 m1=std::min((*it).second,m1);
1609 int m2=getMinFamilyIdInArrays();
1610 return std::min(m1,m2);
1614 * This method only considers the maps. The contain of family array is ignored here.
1616 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1618 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1620 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1622 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1623 v.insert((*it).second);
1624 ret->alloc((int)v.size(),1);
1625 std::copy(v.begin(),v.end(),ret->getPointer());
1630 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1632 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1634 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1636 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1637 MCAuto<DataArrayInt> ret;
1638 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1640 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1641 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1642 if((DataArrayInt *) ret)
1643 ret=dv->buildUnion(ret);
1651 * true is returned if no modification has been needed. false if family
1652 * renumbering has been needed.
1654 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1656 std::vector<int> levs=getNonEmptyLevelsExt();
1657 std::set<int> allFamIds;
1658 int maxId=getMaxFamilyId()+1;
1659 std::map<int,std::vector<int> > famIdsToRenum;
1660 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1662 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1665 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1667 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1669 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1671 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1674 if(famIdsToRenum.empty())
1676 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1677 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1679 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1680 int *famIdsToChange=fam->getPointer();
1681 std::map<int,int> ren;
1682 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1684 if(allIds->presenceOfValue(*it3))
1686 std::string famName=getFamilyNameGivenId(*it3);
1687 std::vector<std::string> grps=getGroupsOnFamily(famName);
1690 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1691 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1692 addFamilyOnGrp((*it4),newFam);
1695 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1696 for(const int *id=ids->begin();id!=ids->end();id++)
1697 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1703 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1704 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1705 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1706 * This method will throw an exception if a same family id is detected in different level.
1707 * \warning This policy is the opposite of those in MED file documentation ...
1709 void MEDFileMesh::normalizeFamIdsTrio()
1711 ensureDifferentFamIdsPerLevel();
1712 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1713 std::vector<int> levs=getNonEmptyLevelsExt();
1714 std::set<int> levsS(levs.begin(),levs.end());
1715 std::set<std::string> famsFetched;
1716 std::map<std::string,int> families;
1717 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1720 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1724 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1725 std::map<int,int> ren;
1726 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1728 int nbOfTuples=fam->getNumberOfTuples();
1729 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1730 for(int *w=start;w!=start+nbOfTuples;w++)
1732 for(const int *it=tmp->begin();it!=tmp->end();it++)
1734 if(allIds->presenceOfValue(*it))
1736 std::string famName=getFamilyNameGivenId(*it);
1737 families[famName]=ren[*it];
1738 famsFetched.insert(famName);
1743 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1746 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1750 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1751 std::map<int,int> ren;
1752 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1754 int nbOfTuples=fam->getNumberOfTuples();
1755 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1756 for(int *w=start;w!=start+nbOfTuples;w++)
1758 for(const int *it=tmp->begin();it!=tmp->end();it++)
1760 if(allIds->presenceOfValue(*it))
1762 std::string famName=getFamilyNameGivenId(*it);
1763 families[famName]=ren[*it];
1764 famsFetched.insert(famName);
1769 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1771 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1774 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1775 fam->fillWithZero();
1776 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1777 if(allIds->presenceOfValue(*it3))
1779 std::string famName=getFamilyNameGivenId(*it3);
1780 families[famName]=0;
1781 famsFetched.insert(famName);
1786 std::vector<std::string> allFams=getFamiliesNames();
1787 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1788 std::set<std::string> unFetchedIds;
1789 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1790 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1791 families[*it4]=_families[*it4];
1796 * This method normalizes fam id with the following policy.
1797 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1798 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1799 * This method will throw an exception if a same family id is detected in different level.
1801 void MEDFileMesh::normalizeFamIdsMEDFile()
1803 ensureDifferentFamIdsPerLevel();
1804 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1805 std::vector<int> levs=getNonEmptyLevelsExt();
1806 std::set<int> levsS(levs.begin(),levs.end());
1807 std::set<std::string> famsFetched;
1808 std::map<std::string,int> families;
1810 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1813 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1816 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1817 std::map<int,int> ren;
1818 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1820 int nbOfTuples=fam->getNumberOfTuples();
1821 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1822 for(int *w=start;w!=start+nbOfTuples;w++)
1824 for(const int *it=tmp->begin();it!=tmp->end();it++)
1826 if(allIds->presenceOfValue(*it))
1828 std::string famName=getFamilyNameGivenId(*it);
1829 families[famName]=ren[*it];
1830 famsFetched.insert(famName);
1836 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1838 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1841 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1842 std::map<int,int> ren;
1843 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1845 int nbOfTuples=fam->getNumberOfTuples();
1846 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1847 for(int *w=start;w!=start+nbOfTuples;w++)
1849 for(const int *it=tmp->begin();it!=tmp->end();it++)
1851 if(allIds->presenceOfValue(*it))
1853 std::string famName=getFamilyNameGivenId(*it);
1854 families[famName]=ren[*it];
1855 famsFetched.insert(famName);
1861 std::vector<std::string> allFams=getFamiliesNames();
1862 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1863 std::set<std::string> unFetchedIds;
1864 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1865 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1866 families[*it4]=_families[*it4];
1871 * Returns a name of the family by its id. If there are several families having the given
1872 * id, the name first in lexical order is returned.
1873 * \param [in] id - the id of the family whose name is required.
1874 * \return std::string - the name of the found family.
1875 * \throw If no family with the given \a id exists.
1877 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1879 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1880 if((*it).second==id)
1882 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1883 throw INTERP_KERNEL::Exception(oss.str().c_str());
1887 * Returns a string describing \a this mesh. This description includes the mesh name and
1888 * the mesh description string.
1889 * \return std::string - the mesh information string.
1891 std::string MEDFileMesh::simpleRepr() const
1893 std::ostringstream oss;
1894 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1895 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1896 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1901 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1902 * an empty one is created.
1904 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1906 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1909 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1910 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1911 arr->fillWithZero();
1912 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1913 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1917 * Returns ids of mesh entities contained in a given group of a given dimension.
1918 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1920 * \param [in] grp - the name of the group of interest.
1921 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1922 * returned instead of ids.
1923 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1924 * numbers, if available and required, of mesh entities of the group. The caller
1925 * is to delete this array using decrRef() as it is no more needed.
1926 * \throw If the name of a nonexistent group is specified.
1927 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1929 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1931 std::vector<std::string> tmp(1);
1933 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1939 * Returns ids of mesh entities contained in given groups of a given dimension.
1940 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1942 * \param [in] grps - the names of the groups of interest.
1943 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1944 * returned instead of ids.
1945 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1946 * numbers, if available and required, of mesh entities of the groups. The caller
1947 * is to delete this array using decrRef() as it is no more needed.
1948 * \throw If the name of a nonexistent group is present in \a grps.
1949 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1951 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1953 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1954 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1958 * Returns ids of mesh entities contained in a given family of a given dimension.
1959 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1961 * \param [in] fam - the name of the family of interest.
1962 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1963 * returned instead of ids.
1964 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1965 * numbers, if available and required, of mesh entities of the family. The caller
1966 * is to delete this array using decrRef() as it is no more needed.
1967 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1969 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1971 std::vector<std::string> tmp(1);
1973 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1979 * Returns ids of nodes contained in a given group.
1980 * \param [in] grp - the name of the group of interest.
1981 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1982 * returned instead of ids.
1983 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1984 * numbers, if available and required, of nodes of the group. The caller
1985 * is to delete this array using decrRef() as it is no more needed.
1986 * \throw If the name of a nonexistent group is specified.
1987 * \throw If the family field is missing for nodes.
1989 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1991 std::vector<std::string> tmp(1);
1993 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1999 * Returns ids of nodes contained in given groups.
2000 * \param [in] grps - the names of the groups of interest.
2001 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2002 * returned instead of ids.
2003 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2004 * numbers, if available and required, of nodes of the groups. The caller
2005 * is to delete this array using decrRef() as it is no more needed.
2006 * \throw If the name of a nonexistent group is present in \a grps.
2007 * \throw If the family field is missing for nodes.
2009 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
2011 return getGroupsArr(1,grps,renum);
2015 * Returns ids of nodes contained in a given group.
2016 * \param [in] grp - the name of the group of interest.
2017 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2018 * returned instead of ids.
2019 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2020 * numbers, if available and required, of nodes of the group. The caller
2021 * is to delete this array using decrRef() as it is no more needed.
2022 * \throw If the name of a nonexistent group is specified.
2023 * \throw If the family field is missing for nodes.
2025 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
2027 std::vector<std::string> tmp(1);
2029 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
2035 * Returns ids of nodes contained in given families.
2036 * \param [in] fams - the names of the families of interest.
2037 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2038 * returned instead of ids.
2039 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2040 * numbers, if available and required, of nodes of the families. The caller
2041 * is to delete this array using decrRef() as it is no more needed.
2042 * \throw If the family field is missing for nodes.
2044 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2046 return getFamiliesArr(1,fams,renum);
2050 * Adds groups of given dimension and creates corresponding families and family fields
2051 * given ids of mesh entities of each group.
2052 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2053 * \param [in] grps - a sequence of arrays of ids each describing a group.
2054 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2056 * \throw If names of some groups in \a grps are equal.
2057 * \throw If \a grps includes a group with an empty name.
2058 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2059 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2061 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2065 std::set<std::string> grpsName;
2066 std::vector<std::string> grpsName2(grps.size());
2069 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2071 grpsName.insert((*it)->getName());
2072 grpsName2[i]=(*it)->getName();
2074 if(grpsName.size()!=grps.size())
2075 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2076 if(grpsName.find(std::string(""))!=grpsName.end())
2077 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2078 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2079 MCAuto<DataArrayInt> fam;
2080 std::vector< std::vector<int> > fidsOfGroups;
2083 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2087 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2088 for(unsigned int ii=0;ii<grps.size();ii++)
2090 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2091 grps2[ii]->setName(grps[ii]->getName());
2093 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2094 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2097 if(!_families.empty())
2098 offset=getMaxAbsFamilyId()+1;
2099 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2100 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2101 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2102 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2106 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2107 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2108 * For the moment, the two last input parameters are not taken into account.
2110 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2112 std::map<int,std::string> famInv;
2113 for(const int *it=famIds->begin();it!=famIds->end();it++)
2115 std::ostringstream oss;
2116 oss << "Family_" << (*it);
2117 _families[oss.str()]=(*it);
2118 famInv[*it]=oss.str();
2121 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2123 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2125 _groups[grpNames[i]].push_back(famInv[*it2]);
2130 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2132 std::vector<int> levs(getNonEmptyLevels());
2133 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2134 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2136 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2137 ret.insert(ret.end(),elts.begin(),elts.end());
2143 * \sa getAllDistributionOfTypes
2145 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2147 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2148 return mLev->getDistributionOfTypes();
2151 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2153 loadLL(fid,mName,dt,it,mrs);
2154 loadJointsFromFile(fid);
2155 loadEquivalences(fid);
2158 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2160 famArr->applyLin(offset>0?1:-1,offset,0);
2161 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2164 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2165 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2170 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2171 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2172 * If this method fails to find such a name it will throw an exception.
2174 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2177 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2180 std::size_t len=nameTry.length();
2181 for(std::size_t ii=1;ii<len;ii++)
2183 std::string tmp=nameTry.substr(ii,len-ii);
2184 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2190 for(std::size_t i=1;i<30;i++)
2192 std::string tmp1(nameTry.at(0),i);
2194 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2200 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2202 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2204 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2207 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2209 std::size_t nbOfChunks=code.size()/3;
2210 if(code.size()%3!=0)
2211 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2213 for(std::size_t i=0;i<nbOfChunks;i++)
2222 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2223 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2224 * If _name is not empty and that 'm' has the same name nothing is done.
2225 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2227 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2230 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2235 std::string name(m->getName());
2240 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2241 oss << name << "' ! Names must match !";
2242 throw INTERP_KERNEL::Exception(oss.str().c_str());
2246 if(_desc_name.empty())
2247 _desc_name=m->getDescription();
2250 std::string name(m->getDescription());
2253 if(_desc_name!=name)
2255 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2256 oss << name << "' ! Names must match !";
2257 throw INTERP_KERNEL::Exception(oss.str().c_str());
2263 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2265 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2266 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2268 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2269 oss << " - Groups lying on this family : ";
2270 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2271 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2272 oss << std::endl << std::endl;
2277 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2278 * file. The mesh to load is specified by its name and numbers of a time step and an
2280 * \param [in] fileName - the name of MED file to read.
2281 * \param [in] mName - the name of the mesh to read.
2282 * \param [in] dt - the number of a time step.
2283 * \param [in] it - the number of an iteration.
2284 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2285 * mesh using decrRef() as it is no more needed.
2286 * \throw If the file is not readable.
2287 * \throw If there is no mesh with given attributes in the file.
2288 * \throw If the mesh in the file is not an unstructured one.
2290 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2292 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2293 return New(fid,mName,dt,it,mrs);
2296 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2298 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2302 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2303 * file. The first mesh in the file is loaded.
2304 * \param [in] fileName - the name of MED file to read.
2305 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2306 * mesh using decrRef() as it is no more needed.
2307 * \throw If the file is not readable.
2308 * \throw If there is no meshes in the file.
2309 * \throw If the mesh in the file is not an unstructured one.
2311 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2313 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2314 return New(fid,mrs);
2318 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2320 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2323 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2324 throw INTERP_KERNEL::Exception(oss.str().c_str());
2327 MEDCoupling::MEDCouplingMeshType meshType;
2329 MEDCoupling::MEDCouplingAxisType dummy3;
2330 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2331 return T::New(fid,ms.front(),dt,it,mrs);
2334 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2336 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2340 * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2341 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2343 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2346 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2347 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2348 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2349 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2351 m2D->setCoords(m3D->getCoords());
2352 ret->setMeshAtLevel(0,m3D);
2353 ret->setMeshAtLevel(-1,m2D);
2354 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2359 * Returns an empty instance of MEDFileUMesh.
2360 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2361 * mesh using decrRef() as it is no more needed.
2363 MEDFileUMesh *MEDFileUMesh::New()
2365 return new MEDFileUMesh;
2369 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2370 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2371 * \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.
2372 * 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
2373 * at most the memory consumtion.
2375 * \param [in] fileName - the name of the file.
2376 * \param [in] mName - the name of the mesh to be read.
2377 * \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.
2378 * \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.
2379 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2380 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2381 * \param [in] mrs - the request for what to be loaded.
2382 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2384 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)
2386 MEDFileUtilities::CheckFileForRead(fileName);
2387 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2388 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2392 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2393 * This method is \b NOT wrapped into python.
2395 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)
2397 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2398 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2402 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2404 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2405 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2409 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2411 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2412 ret.push_back((const DataArrayDouble*)_coords);
2413 ret.push_back((const DataArrayInt *)_fam_coords);
2414 ret.push_back((const DataArrayInt *)_num_coords);
2415 ret.push_back((const DataArrayInt *)_global_num_coords);
2416 ret.push_back((const DataArrayInt *)_rev_num_coords);
2417 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2418 ret.push_back((const PartDefinition *)_part_coords);
2419 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2420 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2421 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2422 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2426 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2428 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2432 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2434 return new MEDFileUMesh;
2437 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2439 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2440 ret->deepCpyEquivalences(*this);
2441 if(_coords.isNotNull())
2442 ret->_coords=_coords->deepCopy();
2443 if(_fam_coords.isNotNull())
2444 ret->_fam_coords=_fam_coords->deepCopy();
2445 if(_num_coords.isNotNull())
2446 ret->_num_coords=_num_coords->deepCopy();
2447 if(_global_num_coords.isNotNull())
2448 ret->_global_num_coords=_global_num_coords->deepCopy();
2449 if(_rev_num_coords.isNotNull())
2450 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2451 if(_name_coords.isNotNull())
2452 ret->_name_coords=_name_coords->deepCopy();
2454 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2456 if((const MEDFileUMeshSplitL1 *)(*it))
2457 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2459 if((const PartDefinition*)_part_coords)
2460 ret->_part_coords=_part_coords->deepCopy();
2465 * Checks if \a this and another mesh are equal.
2466 * \param [in] other - the mesh to compare with.
2467 * \param [in] eps - a precision used to compare real values.
2468 * \param [in,out] what - the string returning description of unequal data.
2469 * \return bool - \c true if the meshes are equal, \c false, else.
2471 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2473 if(!MEDFileMesh::isEqual(other,eps,what))
2475 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2478 what="Mesh types differ ! This is unstructured and other is NOT !";
2481 clearNonDiscrAttributes();
2482 otherC->clearNonDiscrAttributes();
2483 const DataArrayDouble *coo1=_coords;
2484 const DataArrayDouble *coo2=otherC->_coords;
2485 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2487 what="Mismatch of coordinates ! One is defined and not other !";
2492 bool ret=coo1->isEqual(*coo2,eps);
2495 what="Coords differ !";
2500 const DataArrayInt *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2501 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2503 what="Mismatch of families arr on nodes ! One is defined and not other !";
2508 bool ret=famc1->isEqual(*famc2);
2511 what="Families arr on node differ !";
2517 const DataArrayInt *numc1(_num_coords),*numc2(otherC->_num_coords);
2518 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2520 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2525 bool ret=numc1->isEqual(*numc2);
2528 what="Numbering arr on node differ !";
2534 const DataArrayInt *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2535 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2537 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2542 bool ret=gnumc1->isEqual(*gnumc2);
2545 what="Global numbering arr on node differ !";
2551 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2552 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2554 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2559 bool ret=namec1->isEqual(*namec2);
2562 what="Names arr on node differ !";
2567 if(_ms.size()!=otherC->_ms.size())
2569 what="Number of levels differs !";
2572 std::size_t sz=_ms.size();
2573 for(std::size_t i=0;i<sz;i++)
2575 const MEDFileUMeshSplitL1 *s1=_ms[i];
2576 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2577 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2579 what="Mismatch of presence of sub levels !";
2584 bool ret=s1->isEqual(s2,eps,what);
2589 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2592 if((!pd0 && pd1) || (pd0 && !pd1))
2594 what=std::string("node part def is defined only for one among this or other !");
2597 return pd0->isEqual(pd1,what);
2601 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2602 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2603 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2604 * \throw if internal family array is inconsistent
2605 * \sa checkSMESHConsistency()
2607 void MEDFileUMesh::checkConsistency() const
2609 if(!_coords || !_coords->isAllocated())
2612 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2614 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2615 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2616 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2620 int nbCoo = _coords->getNumberOfTuples();
2621 if (_fam_coords.isNotNull())
2622 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2623 if (_num_coords.isNotNull())
2625 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2627 int maxValue=_num_coords->getMaxValue(pos);
2628 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2629 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2631 if (_global_num_coords.isNotNull())
2633 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2635 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2636 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2637 if (_num_coords && !_num_coords->hasUniqueValues())
2638 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2640 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2641 // Now sub part check:
2642 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2643 it != _ms.end(); it++)
2644 (*it)->checkConsistency();
2649 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2650 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2651 * entities as it likes), or non overlapping between all sub-levels.
2652 * \throw if the condition above is not respected
2654 void MEDFileUMesh::checkSMESHConsistency() const
2657 // For all sub-levels, numbering is either always null or with void intersection:
2660 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2661 std::vector< const DataArrayInt * > v;
2662 bool voidOrNot = ((*it)->_num == 0);
2663 for (it++; it != _ms.end(); it++)
2664 if( ((*it)->_num == 0) != voidOrNot )
2665 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2666 else if (!voidOrNot)
2667 v.push_back((*it)->_num);
2670 // don't forget the 1st one:
2671 v.push_back(_ms[0]->_num);
2672 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2673 if (inter->getNumberOfTuples())
2674 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2680 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2681 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2683 void MEDFileUMesh::clearNodeAndCellNumbers()
2685 _num_coords.nullify();
2686 _rev_num_coords.nullify();
2687 _global_num_coords.nullify();
2688 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2690 (*it)->_num.nullify();
2691 (*it)->_rev_num.nullify();
2692 (*it)->_global_num.nullify();
2697 * Clears redundant attributes of incorporated data arrays.
2699 void MEDFileUMesh::clearNonDiscrAttributes() const
2701 MEDFileMesh::clearNonDiscrAttributes();
2702 if(_coords.isNotNull())
2703 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2704 if(_fam_coords.isNotNull())
2705 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2706 if(_num_coords.isNotNull())
2707 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2708 if(_name_coords.isNotNull())
2709 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2710 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2712 if((*it).isNotNull())
2713 (*it)->clearNonDiscrAttributes();
2717 void MEDFileUMesh::setName(const std::string& name)
2719 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2720 if((*it).isNotNull())
2721 (*it)->setName(name);
2722 MEDFileMesh::setName(name);
2725 MEDFileUMesh::MEDFileUMesh()
2729 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2732 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2734 catch(INTERP_KERNEL::Exception& e)
2740 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2741 * See MEDFileUMesh::LoadPartOf for detailed description.
2745 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)
2747 MEDFileUMeshL2 loaderl2;
2748 MEDCoupling::MEDCouplingMeshType meshType;
2751 MEDCoupling::MEDCouplingAxisType dummy3;
2752 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2753 if(meshType!=UNSTRUCTURED)
2755 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2756 throw INTERP_KERNEL::Exception(oss.str().c_str());
2758 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2759 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2763 * \brief Write joints in a file
2765 void MEDFileMesh::writeJoints(med_idt fid) const
2767 if ( _joints.isNotNull() )
2768 _joints->writeLL(fid);
2772 * \brief Load joints in a file or use provided ones
2774 //================================================================================
2776 * \brief Load joints in a file or use provided ones
2777 * \param [in] fid - MED file descriptor
2778 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2779 * Usually this joints are those just read by another iteration
2780 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2782 //================================================================================
2784 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2786 if ( toUseInstedOfReading )
2787 setJoints( toUseInstedOfReading );
2789 _joints = MEDFileJoints::New( fid, _name );
2792 void MEDFileMesh::loadEquivalences(med_idt fid)
2794 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2796 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2799 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2801 const MEDFileEquivalences *equiv(other._equiv);
2803 _equiv=equiv->deepCopy(this);
2806 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2808 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2809 if(!thisEq && !otherEq)
2811 if(thisEq && otherEq)
2812 return thisEq->isEqual(otherEq,what);
2815 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2820 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2822 const MEDFileEquivalences *equiv(_equiv);
2825 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2826 _equiv->getRepr(oss);
2829 void MEDFileMesh::checkCartesian() const
2831 if(getAxisType()!=AX_CART)
2833 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()) << ").";
2834 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2835 oss << " - call setAxisType(AX_CART)" << std::endl;
2836 oss << " - call cartesianize()";
2837 throw INTERP_KERNEL::Exception(oss.str().c_str());
2842 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2844 int MEDFileMesh::getNumberOfJoints() const
2846 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2850 * \brief Return joints with all adjacent mesh domains
2852 MEDFileJoints * MEDFileMesh::getJoints() const
2854 return const_cast<MEDFileJoints*>(& (*_joints));
2857 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2859 if ( joints != _joints )
2868 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2870 * \sa loadPartUMeshFromFile
2872 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2874 MEDFileUMeshL2 loaderl2;
2875 MEDCoupling::MEDCouplingMeshType meshType;
2878 MEDCoupling::MEDCouplingAxisType axType;
2879 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2880 setAxisType(axType);
2881 if(meshType!=UNSTRUCTURED)
2883 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2884 throw INTERP_KERNEL::Exception(oss.str().c_str());
2886 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2887 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2888 // Structure element part...
2891 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2892 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2896 _elt_str.resize(nModels);
2897 for(int i=0;i<nModels;i++)
2898 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2901 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2903 int lev=loaderl2.getNumberOfLevels();
2905 for(int i=0;i<lev;i++)
2907 if(!loaderl2.emptyLev(i))
2908 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2912 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2914 setName(loaderl2.getName());
2915 setDescription(loaderl2.getDescription());
2916 setUnivName(loaderl2.getUnivName());
2917 setIteration(loaderl2.getIteration());
2918 setOrder(loaderl2.getOrder());
2919 setTimeValue(loaderl2.getTime());
2920 setTimeUnit(loaderl2.getTimeUnit());
2921 _coords=loaderl2.getCoords();
2922 if(!mrs || mrs->isNodeFamilyFieldReading())
2923 _fam_coords=loaderl2.getCoordsFamily();
2924 if(!mrs || mrs->isNodeNumFieldReading())
2925 _num_coords=loaderl2.getCoordsNum();
2926 if(!mrs || mrs->isNodeNameFieldReading())
2927 _name_coords=loaderl2.getCoordsName();
2928 if(!mrs || mrs->isGlobalNodeNumFieldReading())
2929 _global_num_coords=loaderl2.getCoordsGlobalNum();
2930 _part_coords=loaderl2.getPartDefOfCoo();
2934 MEDFileUMesh::~MEDFileUMesh()
2938 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2940 const DataArrayDouble *coo=_coords;
2941 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2942 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2943 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2944 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2945 int spaceDim=coo?coo->getNumberOfComponents():0;
2948 mdim=getMeshDimension();
2949 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2950 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2951 for(int i=0;i<spaceDim;i++)
2953 std::string info=coo->getInfoOnComponent(i);
2955 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2956 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
2957 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
2959 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2961 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2962 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2963 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
2964 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2965 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2966 (*it)->write(fid,meshName,mdim);
2967 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2971 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2972 * \return std::vector<int> - a sequence of the relative dimensions.
2974 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2976 std::vector<int> ret;
2978 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2979 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2986 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2987 * \return std::vector<int> - a sequence of the relative dimensions.
2989 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2991 std::vector<int> ret0=getNonEmptyLevels();
2992 if((const DataArrayDouble *) _coords)
2994 std::vector<int> ret(ret0.size()+1);
2996 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3002 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
3004 std::vector<int> ret;
3005 const DataArrayInt *famCoo(_fam_coords);
3009 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3011 const MEDFileUMeshSplitL1 *cur(*it);
3013 if(cur->getFamilyField())
3019 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3021 std::vector<int> ret;
3022 if(_num_coords.isNotNull())
3025 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3027 const MEDFileUMeshSplitL1 *cur(*it);
3029 if(cur->getNumberField())
3035 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3037 std::vector<int> ret;
3038 const DataArrayAsciiChar *nameCoo(_name_coords);
3042 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3044 const MEDFileUMeshSplitL1 *cur(*it);
3046 if(cur->getNameField())
3053 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3054 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3055 * \param [in] fams - the name of the family of interest.
3056 * \return std::vector<int> - a sequence of the relative dimensions.
3058 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3060 std::vector<int> ret;
3061 std::vector<int> levs(getNonEmptyLevels());
3062 std::vector<int> famIds(getFamiliesIds(fams));
3063 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3064 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3070 * Returns all relative mesh levels (including nodes) where given families are defined.
3071 * \param [in] fams - the names of the families of interest.
3072 * \return std::vector<int> - a sequence of the relative dimensions.
3074 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3076 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
3077 const DataArrayInt *famCoords(_fam_coords);
3080 std::vector<int> famIds(getFamiliesIds(fams));
3081 if(famCoords->presenceOfValue(famIds))
3083 std::vector<int> ret(ret0.size()+1);
3085 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3092 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3094 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3095 if((const DataArrayInt *)_fam_coords)
3097 int val=_fam_coords->getMaxValue(tmp);
3098 ret=std::max(ret,std::abs(val));
3100 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3102 if((const MEDFileUMeshSplitL1 *)(*it))
3104 const DataArrayInt *da=(*it)->getFamilyField();
3107 int val=da->getMaxValue(tmp);
3108 ret=std::max(ret,std::abs(val));
3115 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3117 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3118 if((const DataArrayInt *)_fam_coords)
3120 int val=_fam_coords->getMaxValue(tmp);
3121 ret=std::max(ret,val);
3123 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3125 if((const MEDFileUMeshSplitL1 *)(*it))
3127 const DataArrayInt *da=(*it)->getFamilyField();
3130 int val=da->getMaxValue(tmp);
3131 ret=std::max(ret,val);
3138 int MEDFileUMesh::getMinFamilyIdInArrays() const
3140 int ret=std::numeric_limits<int>::max(),tmp=-1;
3141 if((const DataArrayInt *)_fam_coords)
3143 int val=_fam_coords->getMinValue(tmp);
3144 ret=std::min(ret,val);
3146 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3148 if((const MEDFileUMeshSplitL1 *)(*it))
3150 const DataArrayInt *da=(*it)->getFamilyField();
3153 int val=da->getMinValue(tmp);
3154 ret=std::min(ret,val);
3162 * Returns the dimension on cells in \a this mesh.
3163 * \return int - the mesh dimension.
3164 * \throw If there are no cells in this mesh.
3166 int MEDFileUMesh::getMeshDimension() const
3169 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3170 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3171 return (*it)->getMeshDimension()+lev;
3172 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3176 * Returns the space dimension of \a this mesh that is equal to number of components in
3177 * the node coordinates array.
3178 * \return int - the space dimension of \a this mesh.
3179 * \throw If the node coordinates array is not available.
3181 int MEDFileUMesh::getSpaceDimension() const
3183 const DataArrayDouble *coo=_coords;
3185 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3186 return coo->getNumberOfComponents();
3190 * Returns a string describing \a this mesh.
3191 * \return std::string - the mesh information string.
3193 std::string MEDFileUMesh::simpleRepr() const
3195 std::ostringstream oss;
3196 oss << MEDFileMesh::simpleRepr();
3197 const DataArrayDouble *coo=_coords;
3198 oss << "- The dimension of the space is ";
3199 static const char MSG1[]= "*** NO COORDS SET ***";
3200 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3202 oss << _coords->getNumberOfComponents() << std::endl;
3204 oss << MSG1 << std::endl;
3205 oss << "- Type of the mesh : UNSTRUCTURED\n";
3206 oss << "- Number of nodes : ";
3208 oss << _coords->getNumberOfTuples() << std::endl;
3210 oss << MSG1 << std::endl;
3211 std::size_t nbOfLev=_ms.size();
3212 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3213 for(std::size_t i=0;i<nbOfLev;i++)
3215 const MEDFileUMeshSplitL1 *lev=_ms[i];
3216 oss << " - Level #" << -((int) i) << " has dimension : ";
3219 oss << lev->getMeshDimension() << std::endl;
3220 lev->simpleRepr(oss);
3223 oss << MSG2 << std::endl;
3225 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3228 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3229 oss << "- Names of coordinates :" << std::endl;
3230 std::vector<std::string> vars=coo->getVarsOnComponent();
3231 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3232 oss << std::endl << "- Units of coordinates : " << std::endl;
3233 std::vector<std::string> units=coo->getUnitsOnComponent();
3234 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3236 oss << std::endl << std::endl;
3238 getEquivalencesRepr(oss);
3243 * Returns a full textual description of \a this mesh.
3244 * \return std::string - the string holding the mesh description.
3246 std::string MEDFileUMesh::advancedRepr() const
3248 return simpleRepr();
3252 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3253 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3254 * \return int - the number of entities.
3255 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3257 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3259 if(meshDimRelToMaxExt==1)
3261 if(!((const DataArrayDouble *)_coords))
3262 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3263 return _coords->getNumberOfTuples();
3265 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3269 * Returns the family field for mesh entities of a given dimension.
3270 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3271 * \return const DataArrayInt * - the family field. It is an array of ids of families
3272 * each mesh entity belongs to. It can be \c NULL.
3274 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3276 if(meshDimRelToMaxExt==1)
3278 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3279 return l1->getFamilyField();
3282 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3284 if(meshDimRelToMaxExt==1)
3286 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3287 return l1->getFamilyField();
3291 * Returns the optional numbers of mesh entities of a given dimension.
3292 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3293 * \return const DataArrayInt * - the array of the entity numbers.
3294 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3296 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3298 if(meshDimRelToMaxExt==1)
3300 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3301 return l1->getNumberField();
3304 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3306 if(meshDimRelToMaxExt==1)
3307 return _name_coords;
3308 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3309 return l1->getNameField();
3312 MCAuto<DataArrayInt> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3314 if(meshDimRelToMaxExt!=1)
3315 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3316 return _global_num_coords;
3320 * 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).
3322 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3323 * \param [in] gt - The input geometric type for which the part definition is requested.
3324 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3326 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3328 if(meshDimRelToMaxExt==1)
3329 return _part_coords;
3330 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3331 return l1->getPartDef(gt);
3334 int MEDFileUMesh::getNumberOfNodes() const
3336 const DataArrayDouble *coo(_coords);
3338 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3339 return coo->getNumberOfTuples();
3342 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3344 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3345 return l1->getNumberOfCells();
3348 bool MEDFileUMesh::hasImplicitPart() const
3353 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3355 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3358 void MEDFileUMesh::releaseImplicitPartIfAny() const
3362 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3364 std::size_t sz(st.getNumberOfItems());
3365 for(std::size_t i=0;i<sz;i++)
3367 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3368 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3369 if(st[i].getPflName().empty())
3370 m->computeNodeIdsAlg(nodesFetched);
3373 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3374 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3375 m2->computeNodeIdsAlg(nodesFetched);
3380 MEDFileMesh *MEDFileUMesh::cartesianize() const
3382 if(getAxisType()==AX_CART)
3385 return const_cast<MEDFileUMesh *>(this);
3389 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3390 const DataArrayDouble *coords(_coords);
3392 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3393 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3394 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3395 if((const MEDFileUMeshSplitL1 *)(*it))
3396 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3397 ret->_coords=coordsCart;
3398 ret->setAxisType(AX_CART);
3403 bool MEDFileUMesh::presenceOfStructureElements() const
3405 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3406 if((*it).isNotNull())
3411 void MEDFileUMesh::killStructureElements()
3417 * Returns the optional numbers of mesh entities of a given dimension transformed using
3418 * DataArrayInt::invertArrayN2O2O2N().
3419 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3420 * \return const DataArrayInt * - the array of the entity numbers transformed using
3421 * DataArrayInt::invertArrayN2O2O2N().
3422 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3424 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3426 if(meshDimRelToMaxExt==1)
3428 if(_num_coords.isNull())
3429 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3430 return _rev_num_coords;
3432 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3433 return l1->getRevNumberField();
3437 * Returns a pointer to the node coordinates array of \a this mesh \b without
3438 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3440 DataArrayDouble *MEDFileUMesh::getCoords() const
3443 MCAuto<DataArrayDouble> tmp(_coords);
3444 if((DataArrayDouble *)tmp)
3452 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3453 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3455 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3456 * \param [in] grp - the name of the group whose mesh entities are included in the
3458 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3459 * according to the optional numbers of entities, if available.
3460 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3461 * delete this mesh using decrRef() as it is no more needed.
3462 * \throw If the name of a nonexistent group is specified.
3463 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3465 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3468 synchronizeTinyInfoOnLeaves();
3469 std::vector<std::string> tmp(1);
3471 return getGroups(meshDimRelToMaxExt,tmp,renum);
3475 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3476 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3478 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3479 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3481 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3482 * according to the optional numbers of entities, if available.
3483 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3484 * delete this mesh using decrRef() as it is no more needed.
3485 * \throw If a name of a nonexistent group is present in \a grps.
3486 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3488 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3491 synchronizeTinyInfoOnLeaves();
3492 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3493 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3494 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3495 zeRet->setName(grps[0]);
3496 return zeRet.retn();
3500 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3501 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3503 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3504 * \param [in] fam - the name of the family whose mesh entities are included in the
3506 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3507 * according to the optional numbers of entities, if available.
3508 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3509 * delete this mesh using decrRef() as it is no more needed.
3510 * \throw If a name of a nonexistent family is present in \a grps.
3511 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3513 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3516 synchronizeTinyInfoOnLeaves();
3517 std::vector<std::string> tmp(1);
3519 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3523 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3524 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3526 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3527 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3529 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3530 * according to the optional numbers of entities, if available.
3531 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3532 * delete this mesh using decrRef() as it is no more needed.
3533 * \throw If a name of a nonexistent family is present in \a fams.
3534 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3536 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3539 synchronizeTinyInfoOnLeaves();
3540 if(meshDimRelToMaxExt==1)
3542 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3543 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3544 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3548 std::vector<int> famIds=getFamiliesIds(fams);
3549 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3550 MCAuto<MEDCouplingUMesh> zeRet;
3552 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3554 zeRet=l1->getFamilyPart(0,0,renum);
3555 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3556 zeRet->setName(fams[0]);
3557 return zeRet.retn();
3561 * Returns ids of mesh entities contained in given families of a given dimension.
3562 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3564 * \param [in] fams - the names of the families of interest.
3565 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3566 * returned instead of ids.
3567 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3568 * numbers, if available and required, of mesh entities of the families. The caller
3569 * is to delete this array using decrRef() as it is no more needed.
3570 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3572 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3574 std::vector<int> famIds=getFamiliesIds(fams);
3575 if(meshDimRelToMaxExt==1)
3577 if((const DataArrayInt *)_fam_coords)
3579 MCAuto<DataArrayInt> da;
3581 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3583 da=_fam_coords->findIdsEqualList(0,0);
3585 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3590 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3592 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3594 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3596 return l1->getFamilyPartArr(0,0,renum);
3600 * Returns a MEDCouplingUMesh of a given relative dimension.
3601 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3602 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3603 * To build a valid MEDCouplingUMesh from the returned one in this case,
3604 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3605 * \param [in] meshDimRelToMax - the relative dimension of interest.
3606 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3607 * optional numbers of mesh entities.
3608 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3609 * delete using decrRef() as it is no more needed.
3610 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3612 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3615 synchronizeTinyInfoOnLeaves();
3616 if(meshDimRelToMaxExt==1)
3620 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3621 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3622 umesh->setCoords(cc);
3623 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3624 umesh->setName(getName());
3628 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3629 return l1->getWholeMesh(renum);
3632 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3634 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3635 return l1->getDistributionOfTypes();
3639 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3640 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3641 * optional numbers of mesh entities.
3642 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3643 * delete using decrRef() as it is no more needed.
3644 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3646 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3648 return getMeshAtLevel(0,renum);
3652 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3653 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3654 * optional numbers of mesh entities.
3655 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3656 * delete using decrRef() as it is no more needed.
3657 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3659 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3661 return getMeshAtLevel(-1,renum);
3665 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3666 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3667 * optional numbers of mesh entities.
3668 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3669 * delete using decrRef() as it is no more needed.
3670 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3672 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3674 return getMeshAtLevel(-2,renum);
3678 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3679 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3680 * optional numbers of mesh entities.
3681 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3682 * delete using decrRef() as it is no more needed.
3683 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3685 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3687 return getMeshAtLevel(-3,renum);
3691 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3692 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3693 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3694 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3696 void MEDFileUMesh::forceComputationOfParts() const
3698 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3700 const MEDFileUMeshSplitL1 *elt(*it);
3702 elt->forceComputationOfParts();
3707 * This method returns a vector of mesh parts containing each exactly one geometric type.
3708 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3709 * This method is only for memory aware users.
3710 * The returned pointers are **NOT** new object pointer. No need to mange them.
3712 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3715 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3716 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3720 * This method returns the part of \a this having the geometric type \a gt.
3721 * If such part is not existing an exception will be thrown.
3722 * The returned pointer is **NOT** new object pointer. No need to mange it.
3724 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3727 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3728 int lev=(int)cm.getDimension()-getMeshDimension();
3729 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3730 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3734 * This method returns for each geo types in \a this number of cells with this geo type.
3735 * 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.
3736 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3738 * \sa getDistributionOfTypes
3740 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3742 std::vector< std::pair<int,int> > ret;
3743 std::vector<int> nel(getNonEmptyLevels());
3744 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3746 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3747 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3749 int nbCells(getNumberOfCellsWithType(*it1));
3750 ret.push_back(std::pair<int,int>(*it1,nbCells));
3753 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3758 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3759 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3761 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3763 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3764 return sp->getGeoTypes();
3767 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3769 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3770 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3771 return sp->getNumberOfCellsWithType(ct);
3775 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3776 * \param [in] gt - the geometric type for which the family field is asked.
3777 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3778 * delete using decrRef() as it is no more needed.
3779 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3781 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3783 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3784 int lev=(int)cm.getDimension()-getMeshDimension();
3785 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3786 return sp->extractFamilyFieldOnGeoType(gt);
3790 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3791 * \param [in] gt - the geometric type for which the number field is asked.
3792 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3793 * delete using decrRef() as it is no more needed.
3794 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3796 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3798 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3799 int lev=(int)cm.getDimension()-getMeshDimension();
3800 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3801 return sp->extractNumberFieldOnGeoType(gt);
3805 * This method returns for specified geometric type \a gt the relative level to \a this.
3806 * If the relative level is empty an exception will be thrown.
3808 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3810 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3811 int ret((int)cm.getDimension()-getMeshDimension());
3812 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3816 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3818 if(meshDimRelToMaxExt==1)
3819 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3820 if(meshDimRelToMaxExt>1)
3821 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3822 int tracucedRk=-meshDimRelToMaxExt;
3823 if(tracucedRk>=(int)_ms.size())
3824 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3825 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3826 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3827 return _ms[tracucedRk];
3830 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3832 if(meshDimRelToMaxExt==1)
3833 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3834 if(meshDimRelToMaxExt>1)
3835 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3836 int tracucedRk=-meshDimRelToMaxExt;
3837 if(tracucedRk>=(int)_ms.size())
3838 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3839 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3840 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3841 return _ms[tracucedRk];
3844 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3846 if(-meshDimRelToMax>=(int)_ms.size())
3847 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3849 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3851 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3853 int ref=(*it)->getMeshDimension();
3854 if(ref+i!=meshDim-meshDimRelToMax)
3855 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3861 * Sets the node coordinates array of \a this mesh.
3862 * \param [in] coords - the new node coordinates array.
3863 * \throw If \a coords == \c NULL.
3865 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3868 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3869 if(coords==(DataArrayDouble *)_coords)
3871 coords->checkAllocated();
3872 int nbOfTuples(coords->getNumberOfTuples());
3873 _coords.takeRef(coords);
3874 _fam_coords=DataArrayInt::New();
3875 _fam_coords->alloc(nbOfTuples,1);
3876 _fam_coords->fillWithZero();
3877 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3878 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3879 if((MEDFileUMeshSplitL1 *)(*it))
3880 (*it)->setCoords(coords);
3884 * Change coords without changing anything concerning families and numbering on nodes.
3886 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3889 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3890 if(coords==(DataArrayDouble *)_coords)
3892 coords->checkAllocated();
3893 int nbOfTuples(coords->getNumberOfTuples());
3894 if(_coords.isNull())
3901 int oldNbTuples(_coords->getNumberOfTuples());
3902 if(oldNbTuples!=nbOfTuples)
3903 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3907 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3908 if((MEDFileUMeshSplitL1 *)(*it))
3909 (*it)->setCoords(coords);
3913 * Removes all groups of a given dimension in \a this mesh.
3914 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3915 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3917 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3919 if(meshDimRelToMaxExt==1)
3921 if((DataArrayInt *)_fam_coords)
3922 _fam_coords->fillWithZero();
3925 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3926 l1->eraseFamilyField();
3931 * Removes all families with ids not present in the family fields of \a this mesh.
3933 void MEDFileUMesh::optimizeFamilies()
3935 std::vector<int> levs=getNonEmptyLevelsExt();
3936 std::set<int> allFamsIds;
3937 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3939 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3940 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3942 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3945 std::set<std::string> famNamesToKill;
3946 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3948 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3949 famNamesToKill.insert((*it).first);
3951 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3952 _families.erase(*it);
3953 std::vector<std::string> grpNamesToKill;
3954 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3956 std::vector<std::string> tmp;
3957 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3959 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3960 tmp.push_back(*it2);
3965 tmp.push_back((*it).first);
3967 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3972 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3973 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3974 * The boundary is built according to the following method:
3975 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3976 * coordinates array is extended).
3977 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3978 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3979 * might not be duplicated at all.
3980 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3981 * other side of the group is no more a neighbor)
3982 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3983 * bordering the newly created boundary use the newly computed nodes.
3984 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3985 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3987 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3988 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3990 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3991 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3992 * \sa clearNodeAndCellNumbers()
3994 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3995 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3997 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3998 typedef MCAuto<DataArrayInt> DAInt;
4000 std::vector<int> levs=getNonEmptyLevels();
4001 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
4002 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
4003 MUMesh m0=getMeshAtLevel(0);
4004 MUMesh m1=getMeshAtLevel(-1);
4005 int nbNodes=m0->getNumberOfNodes();
4006 MUMesh m11=getGroup(-1,grpNameM1);
4007 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
4008 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
4009 DAInt nodeIdsToDuplicate(tmp00);
4010 DAInt cellsToModifyConn0(tmp11);
4011 DAInt cellsToModifyConn1(tmp22);
4012 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4013 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4014 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
4015 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4016 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4017 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4018 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4019 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
4020 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4021 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4022 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4023 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4024 DAInt grpIds=getGroupArr(-1,grpNameM1);
4025 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4026 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4027 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4028 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4029 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4030 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4031 m0->setCoords(tmp0->getCoords());
4032 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4033 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4034 m1->setCoords(m0->getCoords());
4035 _coords=m0->getCoords(); _coords->incrRef();
4036 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4037 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4038 DataArrayInt * duplCells;
4039 m1->areCellsIncludedIn(m11, 0, duplCells);
4040 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4041 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4042 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4043 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4044 DAInt szOfCellGrpOfSameType(tmp00);
4045 DAInt idInMsOfCellGrpOfSameType(tmp11);
4047 newm1->setName(getName());
4048 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
4050 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4051 DAInt newFam=DataArrayInt::New();
4052 newFam->alloc(newm1->getNumberOfCells(),1);
4053 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4054 // Positive ID for family of nodes, negative for all the rest.
4056 if (m1->getMeshDimension() == 0)
4057 idd=getMaxFamilyId()+1;
4059 idd=getMinFamilyId()-1;
4060 int globStart=0,start=0,end,globEnd;
4061 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4062 for(int i=0;i<nbOfChunks;i++)
4064 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4065 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4067 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4068 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4069 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4074 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4078 newm1->setCoords(getCoords());
4079 setMeshAtLevel(-1,newm1);
4080 setFamilyFieldArr(-1,newFam);
4081 std::string grpName2(grpNameM1); grpName2+="_dup";
4082 addFamily(grpName2,idd);
4083 addFamilyOnGrp(grpName2,grpName2);
4088 int newNbOfNodes=getCoords()->getNumberOfTuples();
4089 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
4090 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4091 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4095 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4097 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4098 it != _ms.end(); it++)
4101 (*it)->_rev_num = 0;
4103 nodesDuplicated=nodeIdsToDuplicate.retn();
4104 cellsModified=cellsToModifyConn0.retn();
4105 cellsNotModified=cellsToModifyConn1.retn();
4108 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4109 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4112 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4113 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4114 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4116 * \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.
4117 * 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.
4119 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4121 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4122 std::vector<int> levs=getNonEmptyLevels();
4124 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4125 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4128 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4130 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4131 std::vector<int> code1=m->getDistributionOfTypes();
4132 end=PutInThirdComponentOfCodeOffset(code1,start);
4133 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4134 bool hasChanged=m->unPolyze();
4135 DataArrayInt *fake=0;
4136 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4137 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4139 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4142 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4143 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4145 MCAuto<DataArrayInt> famField2,numField2;
4146 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4147 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4148 setMeshAtLevel(*it,m);
4149 std::vector<int> code2=m->getDistributionOfTypes();
4150 end=PutInThirdComponentOfCodeOffset(code2,start);
4151 newCode.insert(newCode.end(),code2.begin(),code2.end());
4153 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4157 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4158 setFamilyFieldArr(*it,newFamField);
4162 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4163 setRenumFieldArr(*it,newNumField);
4168 newCode.insert(newCode.end(),code1.begin(),code1.end());
4174 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4175 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4176 o2nRenumCell=o2nRenumCellRet.retn();
4181 /*! \cond HIDDEN_ITEMS */
4182 struct MEDLoaderAccVisit1
4184 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4185 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4186 int _new_nb_of_nodes;
4191 * 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.
4192 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4193 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4194 * -1 values in returned array means that the corresponding old node is no more used.
4196 * \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
4197 * is modified in \a this.
4198 * \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
4201 DataArrayInt *MEDFileUMesh::zipCoords()
4203 const DataArrayDouble *coo(getCoords());
4205 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4206 int nbOfNodes(coo->getNumberOfTuples());
4207 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4208 std::vector<int> neLevs(getNonEmptyLevels());
4209 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4211 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4212 if(zeLev->isMeshStoredSplitByType())
4214 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4215 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4217 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4221 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4222 mesh->computeNodeIdsAlg(nodeIdsInUse);
4225 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4226 if(nbrOfNodesInUse==nbOfNodes)
4227 return 0;//no need to update _part_coords
4228 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4229 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4230 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4231 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4232 MCAuto<DataArrayInt> newFamCoords;
4233 MCAuto<DataArrayAsciiChar> newNameCoords;
4234 if((const DataArrayInt *)_fam_coords)
4235 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4236 MCAuto<DataArrayInt> newNumCoords,newGlobalNumCoords;
4237 if(_num_coords.isNotNull())
4238 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4239 if(_global_num_coords.isNotNull())
4240 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4241 if(_name_coords.isNotNull())
4242 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4243 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4244 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4246 if((MEDFileUMeshSplitL1*)*it)
4248 (*it)->renumberNodesInConn(ret->begin());
4249 (*it)->setCoords(_coords);
4252 // updates _part_coords
4253 const PartDefinition *pc(_part_coords);
4256 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4257 _part_coords=tmpPD->composeWith(pc);
4263 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4264 * The extraction of \a this is specified by the extractDef \a input map.
4265 * This map tells for each level of cells, the cells kept in the extraction.
4267 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4268 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4270 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4272 std::vector<int> levs(getNonEmptyLevels());
4273 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4274 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4277 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4278 if((*it).second.isNull())
4279 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4282 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4284 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4285 throw INTERP_KERNEL::Exception(oss.str());
4287 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4288 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4289 mPart->computeNodeIdsAlg(fetchedNodes);
4291 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4295 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4297 * \return - a new reference of MEDFileUMesh
4298 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4300 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4302 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4303 std::vector<int> levs(getNonEmptyLevels());
4304 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4307 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4308 if((*it).second.isNull())
4309 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4312 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4314 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4315 throw INTERP_KERNEL::Exception(oss.str());
4317 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4318 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4319 ret->setMeshAtLevel((*it).first,mPart);
4320 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4323 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4324 ret->setFamilyFieldArr((*it).first,famPart);
4328 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4329 ret->setFamilyFieldArr((*it).first,numPart);
4332 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4333 if(it2!=extractDef.end())
4335 const DataArrayDouble *coo(ret->getCoords());
4337 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4338 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4339 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4340 ret->setCoords(cooPart);
4341 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4344 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4345 ret->setFamilyFieldArr(1,famPart);
4349 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4350 ret->setFamilyFieldArr(1,numPart);
4352 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4356 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4357 m->renumberNodesInConn(o2nNodes->begin());
4358 ret->setMeshAtLevel((*it3).first,m);
4365 * This method performs an extrusion along a path defined by \a m1D.
4366 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4367 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4368 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4369 * This method scans all levels in \a this
4370 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4372 * \param [in] m1D - the mesh defining the extrusion path.
4373 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4374 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4376 * \sa MEDCouplingUMesh::buildExtrudedMesh
4378 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4381 if(getMeshDimension()!=2)
4382 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4383 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4384 m1D->checkConsistencyLight();
4385 if(m1D->getMeshDimension()!=1)
4386 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4387 int nbRep(m1D->getNumberOfCells());
4388 std::vector<int> levs(getNonEmptyLevels());
4389 std::vector<std::string> grps(getGroupsNames());
4390 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4391 DataArrayDouble *coords(0);
4392 std::size_t nbOfLevsOut(levs.size()+1);
4393 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4394 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4396 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4397 item=item->clone(false);
4398 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4399 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4400 tmp->changeSpaceDimension(3+(*lev),0.);
4401 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4402 zeList.push_back(elt);
4404 coords=elt->getCoords();
4407 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4408 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4410 (*it)->setName(getName());
4411 (*it)->setCoords(coords);
4413 for(std::size_t ii=0;ii!=zeList.size();ii++)
4416 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4419 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4420 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4421 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4422 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4423 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4424 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4425 std::vector<const MEDCouplingUMesh *> elts(3);
4426 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4427 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4428 elt->setName(getName());
4431 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4432 ret->setMeshAtLevel(lev,elt);
4434 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4435 endLev=endLev->clone(false); endLev->setCoords(coords);
4436 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4437 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4438 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4439 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4440 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4441 endLev->setName(getName());
4442 ret->setMeshAtLevel(levs.back()-1,endLev);
4444 for(std::size_t ii=0;ii!=zeList.size();ii++)
4447 std::vector< MCAuto<DataArrayInt> > outGrps;
4448 std::vector< const DataArrayInt * > outGrps2;
4451 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4453 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4454 if(!grpArr->empty())
4456 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4457 int offset0(zeList[ii]->getNumberOfCells());
4458 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4459 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4460 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4461 grpArr2->setName(oss.str());
4462 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4463 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4464 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4465 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4470 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4472 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4473 if(!grpArr->empty())
4475 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4476 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4477 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4478 for(int iii=0;iii<nbRep;iii++)
4480 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4481 grpArrs2[iii]=grpArrs[iii];
4483 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4484 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4485 std::ostringstream grpName; grpName << *grp << "_extruded";
4486 grpArrExt->setName(grpName.str());
4487 outGrps.push_back(grpArrExt);
4488 outGrps2.push_back(grpArrExt);
4491 ret->setGroupsAtLevel(lev,outGrps2);
4493 std::vector< MCAuto<DataArrayInt> > outGrps;
4494 std::vector< const DataArrayInt * > outGrps2;
4495 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4497 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4498 if(grpArr1->empty())
4500 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4501 std::ostringstream grpName; grpName << *grp << "_top";
4502 grpArr2->setName(grpName.str());
4503 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4504 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4505 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4507 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4512 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4513 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4514 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4516 * \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
4517 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4518 * \param [in] eps - detection threshold for coordinates.
4519 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4521 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4523 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4526 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4527 int initialNbNodes(getNumberOfNodes());
4528 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4529 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4531 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4533 DataArrayDouble *zeCoords(m0->getCoords());
4534 ret->setMeshAtLevel(0,m0);
4535 std::vector<int> levs(getNonEmptyLevels());
4536 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4539 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4540 ret->setFamilyFieldArr(0,famFieldCpy);
4542 famField=getFamilyFieldAtLevel(1);
4545 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4546 fam->fillWithZero();
4547 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4548 ret->setFamilyFieldArr(1,fam);
4550 ret->copyFamGrpMapsFrom(*this);
4551 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4552 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4556 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4557 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4558 if(m1->getMeshDimension()!=0)
4561 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4562 }//kill unused notUsed var
4563 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4565 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4566 MCAuto<DataArrayInt> bSafe(b);
4569 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4570 throw INTERP_KERNEL::Exception(oss.str().c_str());
4572 b->applyLin(1,initialNbNodes);
4573 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4574 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4575 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4576 m1->renumberNodesInConn(renum->begin());
4578 m1->setCoords(zeCoords);
4579 ret->setMeshAtLevel(*lev,m1);
4580 famField=getFamilyFieldAtLevel(*lev);
4583 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4584 ret->setFamilyFieldArr(*lev,famFieldCpy);
4591 * This method converts all quadratic cells in \a this into linear cells.
4592 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4593 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4595 * \param [in] eps - detection threshold for coordinates.
4596 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4598 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4600 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4603 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4604 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4605 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4606 m0->convertQuadraticCellsToLinear();
4608 DataArrayDouble *zeCoords(m0->getCoords());
4609 ret->setMeshAtLevel(0,m0);
4610 std::vector<int> levs(getNonEmptyLevels());
4611 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4614 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4615 ret->setFamilyFieldArr(0,famFieldCpy);
4617 famField=getFamilyFieldAtLevel(1);
4620 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4621 ret->setFamilyFieldArr(1,fam);
4623 ret->copyFamGrpMapsFrom(*this);
4624 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4628 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4629 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4630 m1->convertQuadraticCellsToLinear();
4633 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4634 MCAuto<DataArrayInt> bSafe(b);
4637 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4638 throw INTERP_KERNEL::Exception(oss.str().c_str());
4640 m1->renumberNodesInConn(b->begin());
4641 m1->setCoords(zeCoords);
4642 ret->setMeshAtLevel(*lev,m1);
4643 famField=getFamilyFieldAtLevel(*lev);
4646 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4647 ret->setFamilyFieldArr(*lev,famFieldCpy);
4654 * Computes the symmetry of \a this.
4655 * \return a new object.
4657 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4659 MCAuto<MEDFileUMesh> ret(deepCopy());
4660 DataArrayDouble *myCoo(getCoords());
4663 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4664 ret->setCoordsForced(newCoo);
4669 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4672 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4673 std::size_t sz(meshes.size()),i(0);
4674 std::vector<const DataArrayDouble *> coos(sz);
4675 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4676 for(auto it=meshes.begin();it!=meshes.end();it++,i++)
4679 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4680 coos[i]=(*it)->getCoords();
4681 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4682 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4684 const MEDFileUMesh *ref(meshes[0]);
4685 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4686 std::vector<int> levs(ref->getNonEmptyLevels());
4687 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4688 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4689 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4690 std::map<std::string,int> famNumMap;
4691 std::map<int, std::string> famNumMap_rev;
4692 std::map<std::string, std::vector<std::string> > grpFamMap;
4694 // Identify min family number used:
4696 for(const auto& msh : meshes)
4698 const std::map<std::string,int>& locMap1(msh->getFamilyInfo());
4699 for(const auto& it3 : locMap1)
4700 if(it3.second < min_fam_num)
4701 min_fam_num = it3.second;
4704 for(const auto& msh : meshes)
4706 if(msh->getSpaceDimension()!=spaceDim)
4707 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4708 if(msh->getMeshDimension()!=meshDim)
4709 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4710 if(msh->getNonEmptyLevels()!=levs)
4711 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4713 const std::map<std::string,int>& locMap1(msh->getFamilyInfo());
4714 std::map<std::string, std::string> substitute;
4715 std::map<int, int> substituteN;
4716 bool fam_conflict(false);
4717 for(const auto& it3 : locMap1)
4719 const std::string& famName = it3.first;
4720 int famNum = it3.second;
4721 if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
4723 // Is it used by a group of the current mesh or a group from a previous mesh?
4724 // If not, this is OK (typically -1 familly).
4727 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4728 for(const auto& it4 : locMap2)
4730 const auto& famLst = it4.second;
4731 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4732 { used = true; break; }
4734 // Previous meshes ...
4736 for(const auto& it4 : grpFamMap)
4738 const auto& famLst = it4.second;
4739 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4740 { used = true; break; }
4744 { // Generate a new family name, and a new family number
4745 fam_conflict = true;
4746 std::ostringstream oss;
4747 oss << "Family_" << --min_fam_num; // New ID
4748 std::string new_name(oss.str());
4749 substitute[famName] = new_name;
4750 substituteN[famNum] = min_fam_num;
4751 famNumMap[new_name] = min_fam_num;
4752 famNumMap_rev[min_fam_num] = new_name;
4755 famNumMap[famName] = famNum;
4756 famNumMap_rev[famNum] = famName;
4759 for(const auto& level : levs)
4761 MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
4762 m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
4763 m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
4765 // Family field - substitute new family number if needed:
4768 DataArrayInt *dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
4769 for (const auto& subN : substituteN)
4770 dai->changeValue(subN.first, subN.second);
4771 m_fam[level].push_back(dai);
4774 m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
4777 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4778 for(const auto& grpItem : locMap2)
4780 const auto& famLst = grpItem.second;
4781 // Substitute family name in group description if needed:
4784 std::vector<std::string> newLst(famLst); // Copy needed.
4785 for (const auto& sub : substitute)
4786 std::replace(newLst.begin(), newLst.end(), sub.first, sub.second);
4787 grpFamMap[grpItem.first]=newLst;
4790 grpFamMap[grpItem.first]=famLst;
4793 // Easy part : nodes
4794 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4795 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4796 ret->setCoords(coo);
4797 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4799 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4800 ret->setFamilyFieldArr(1,fam_coo);
4802 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4804 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4805 ret->setRenumFieldArr(1,num_coo);
4808 for(const auto& level : levs)
4810 auto it2(m_mesh.find(level));
4811 if(it2==m_mesh.end())
4812 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4813 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4814 mesh->setCoords(coo); mesh->setName(ref->getName());
4815 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4816 ret->setMeshAtLevel(level,mesh);
4817 auto it3(m_fam.find(level)),it4(m_renum.find(level));
4818 if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
4819 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
4820 if(it4==m_renum.end())
4821 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
4822 // Set new family field if it was defined for all input meshes
4823 const std::vector<const DataArrayInt *>& fams((*it3).second);
4824 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4826 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4827 famm->renumberInPlace(renum->begin());
4828 ret->setFamilyFieldArr(level,famm);
4830 // Set optional number field if defined for all input meshes:
4831 const std::vector<const DataArrayInt *>& renums((*it4).second);
4832 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4834 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4835 renumm->renumberInPlace(renum->begin());
4836 ret->setRenumFieldArr(level,renumm);
4840 ret->setFamilyInfo(famNumMap);
4841 ret->setGroupInfo(grpFamMap);
4842 ret->setName(ref->getName());
4846 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4848 if(getMeshDimension()!=3)
4849 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4850 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4851 if(m3D.isNull() || m2D.isNull())
4852 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4853 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4854 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4858 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4860 clearNonDiscrAttributes();
4861 forceComputationOfParts();
4862 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4863 std::vector<int> layer0;
4864 layer0.push_back(getAxisType());//0 i
4865 layer0.push_back(_order); //1 i
4866 layer0.push_back(_iteration);//2 i
4867 layer0.push_back(getSpaceDimension());//3 i
4868 tinyDouble.push_back(_time);//0 d
4869 tinyStr.push_back(_name);//0 s
4870 tinyStr.push_back(_desc_name);//1 s
4871 for(int i=0;i<getSpaceDimension();i++)
4872 tinyStr.push_back(_coords->getInfoOnComponent(i));
4873 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4874 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4876 tinyStr.push_back((*it).first);
4877 layer0.push_back((*it).second);
4879 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4880 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4882 layer0.push_back((int)(*it0).second.size());
4883 tinyStr.push_back((*it0).first);
4884 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4885 tinyStr.push_back(*it1);
4887 // sizeof(layer0)==4+aa+1+bb layer#0
4888 bigArrayD=_coords;// 0 bd
4889 bigArraysI.push_back(_fam_coords);// 0 bi
4890 bigArraysI.push_back(_num_coords);// 1 bi
4891 const PartDefinition *pd(_part_coords);
4893 layer0.push_back(-1);
4896 std::vector<int> tmp0;
4897 pd->serialize(tmp0,bigArraysI);
4898 tinyInt.push_back(tmp0.size());
4899 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4902 std::vector<int> layer1;
4903 std::vector<int> levs(getNonEmptyLevels());
4904 layer1.push_back((int)levs.size());// 0 i <- key
4905 layer1.insert(layer1.end(),levs.begin(),levs.end());
4906 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4908 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4909 lev->serialize(layer1,bigArraysI);
4911 // put layers all together.
4912 tinyInt.push_back(layer0.size());
4913 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4914 tinyInt.push_back(layer1.size());
4915 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4918 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4919 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4921 int sz0(tinyInt[0]);
4922 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4923 int sz1(tinyInt[sz0+1]);
4924 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4926 std::reverse(layer0.begin(),layer0.end());
4927 std::reverse(layer1.begin(),layer1.end());
4928 std::reverse(tinyDouble.begin(),tinyDouble.end());
4929 std::reverse(tinyStr.begin(),tinyStr.end());
4930 std::reverse(bigArraysI.begin(),bigArraysI.end());
4932 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4933 _order=layer0.back(); layer0.pop_back();
4934 _iteration=layer0.back(); layer0.pop_back();
4935 int spaceDim(layer0.back()); layer0.pop_back();
4936 _time=tinyDouble.back(); tinyDouble.pop_back();
4937 _name=tinyStr.back(); tinyStr.pop_back();
4938 _desc_name=tinyStr.back(); tinyStr.pop_back();
4939 _coords=bigArrayD; _coords->rearrange(spaceDim);
4940 for(int i=0;i<spaceDim;i++)
4942 _coords->setInfoOnComponent(i,tinyStr.back());
4945 int nbOfFams(layer0.back()); layer0.pop_back();
4947 for(int i=0;i<nbOfFams;i++)
4949 _families[tinyStr.back()]=layer0.back();
4950 tinyStr.pop_back(); layer0.pop_back();
4952 int nbGroups(layer0.back()); layer0.pop_back();
4954 for(int i=0;i<nbGroups;i++)
4956 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4957 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4958 std::vector<std::string> fams(nbOfFamsOnGrp);
4959 for(int j=0;j<nbOfFamsOnGrp;j++)
4961 fams[j]=tinyStr.back(); tinyStr.pop_back();
4963 _groups[grpName]=fams;
4965 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4966 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4968 int isPd(layer0.back()); layer0.pop_back();
4971 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4972 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4973 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4976 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4978 int nbLevs(layer1.back()); layer1.pop_back();
4979 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4981 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4982 _ms.resize(maxLev+1);
4983 for(int i=0;i<nbLevs;i++)
4987 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4992 * Adds a group of nodes to \a this mesh.
4993 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4994 * The ids should be sorted and different each other (MED file norm).
4996 * \warning this method can alter default "FAMILLE_ZERO" family.
4997 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4999 * \throw If the node coordinates array is not set.
5000 * \throw If \a ids == \c NULL.
5001 * \throw If \a ids->getName() == "".
5002 * \throw If \a ids does not respect the MED file norm.
5003 * \throw If a group with name \a ids->getName() already exists.
5005 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
5007 const DataArrayDouble *coords(_coords);
5009 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
5010 int nbOfNodes(coords->getNumberOfTuples());
5011 if(_fam_coords.isNull())
5012 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
5014 addGroupUnderground(true,ids,_fam_coords);
5018 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5020 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5021 * The ids should be sorted and different each other (MED file norm).
5023 * \warning this method can alter default "FAMILLE_ZERO" family.
5024 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5026 * \throw If the node coordinates array is not set.
5027 * \throw If \a ids == \c NULL.
5028 * \throw If \a ids->getName() == "".
5029 * \throw If \a ids does not respect the MED file norm.
5030 * \throw If a group with name \a ids->getName() already exists.
5032 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5034 std::vector<int> levs(getNonEmptyLevelsExt());
5035 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
5037 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
5038 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
5040 if(meshDimRelToMaxExt==1)
5041 { addNodeGroup(ids); return ; }
5042 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
5043 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
5044 addGroupUnderground(false,ids,fam);
5048 * Changes a name of a family specified by its id.
5049 * \param [in] id - the id of the family of interest.
5050 * \param [in] newFamName - the new family name.
5051 * \throw If no family with the given \a id exists.
5053 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
5055 std::string oldName=getFamilyNameGivenId(id);
5056 _families.erase(oldName);
5057 _families[newFamName]=id;
5061 * Removes a mesh of a given dimension.
5062 * \param [in] meshDimRelToMax - the relative dimension of interest.
5063 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
5065 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
5067 std::vector<int> levSet=getNonEmptyLevels();
5068 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
5069 if(it==levSet.end())
5070 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
5071 int pos=(-meshDimRelToMax);
5076 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
5077 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5078 * \param [in] m - the new mesh to set.
5079 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5081 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5082 * another node coordinates array.
5083 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5084 * to the existing meshes of other levels of \a this mesh.
5086 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5088 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5089 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5093 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5094 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5095 * \param [in] m - the new mesh to set.
5096 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5097 * writing \a this mesh in a MED file.
5098 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5100 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5101 * another node coordinates array.
5102 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5103 * to the existing meshes of other levels of \a this mesh.
5105 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5107 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5108 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5111 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5113 dealWithTinyInfo(m);
5114 std::vector<int> levSet=getNonEmptyLevels();
5115 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5117 if((DataArrayDouble *)_coords==0)
5119 DataArrayDouble *c=m->getCoords();
5124 if(m->getCoords()!=_coords)
5125 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5126 int sz=(-meshDimRelToMax)+1;
5127 if(sz>=(int)_ms.size())
5129 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5133 return _ms[-meshDimRelToMax];
5137 * This method allows to set at once the content of different levels in \a this.
5138 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5140 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5141 * \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.
5142 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5144 * \throw If \a there is a null pointer in \a ms.
5145 * \sa MEDFileUMesh::setMeshAtLevel
5147 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5151 const MEDCouplingUMesh *mRef=ms[0];
5153 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5154 std::string name(mRef->getName());
5155 const DataArrayDouble *coo(mRef->getCoords());
5158 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5160 const MEDCouplingUMesh *cur(*it);
5162 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5163 if(coo!=cur->getCoords())
5164 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5165 int mdim=cur->getMeshDimension();
5166 zeDim=std::max(zeDim,mdim);
5167 if(s.find(mdim)!=s.end())
5168 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5170 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5172 int mdim=(*it)->getMeshDimension();
5173 setName((*it)->getName());
5174 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5180 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5181 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5182 * The given meshes must share the same node coordinates array.
5183 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5184 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5185 * create in \a this mesh.
5186 * \throw If \a ms is empty.
5187 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5188 * to the existing meshes of other levels of \a this mesh.
5189 * \throw If the meshes in \a ms do not share the same node coordinates array.
5190 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5191 * of the given meshes.
5192 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5193 * \throw If names of some meshes in \a ms are equal.
5194 * \throw If \a ms includes a mesh with an empty name.
5196 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5199 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5200 int sz=(-meshDimRelToMax)+1;
5201 if(sz>=(int)_ms.size())
5203 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5204 DataArrayDouble *coo=checkMultiMesh(ms);
5205 if((DataArrayDouble *)_coords==0)
5211 if((DataArrayDouble *)_coords!=coo)
5212 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5213 std::vector<DataArrayInt *> corr;
5214 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5215 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5216 setMeshAtLevel(meshDimRelToMax,m,renum);
5217 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5218 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5222 * Creates groups at a given level in \a this mesh from a sequence of
5223 * meshes each representing a group.
5224 * The given meshes must share the same node coordinates array.
5225 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5226 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5227 * create in \a this mesh.
5228 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5230 * \throw If \a ms is empty.
5231 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5232 * to the existing meshes of other levels of \a this mesh.
5233 * \throw If the meshes in \a ms do not share the same node coordinates array.
5234 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5235 * of the given meshes.
5236 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5237 * \throw If names of some meshes in \a ms are equal.
5238 * \throw If \a ms includes a mesh with an empty name.
5240 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5243 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5244 int sz=(-meshDimRelToMax)+1;
5245 if(sz>=(int)_ms.size())
5247 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5248 DataArrayDouble *coo=checkMultiMesh(ms);
5249 if((DataArrayDouble *)_coords==0)
5255 if((DataArrayDouble *)_coords!=coo)
5256 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5257 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5258 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5260 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5262 DataArrayInt *arr=0;
5263 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5267 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5268 throw INTERP_KERNEL::Exception(oss.str().c_str());
5271 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5272 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5275 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5277 const DataArrayDouble *ret=ms[0]->getCoords();
5278 int mdim=ms[0]->getMeshDimension();
5279 for(unsigned int i=1;i<ms.size();i++)
5281 ms[i]->checkConsistencyLight();
5282 if(ms[i]->getCoords()!=ret)
5283 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5284 if(ms[i]->getMeshDimension()!=mdim)
5285 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5287 return const_cast<DataArrayDouble *>(ret);
5291 * Sets the family field of a given relative dimension.
5292 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5293 * the family field is set.
5294 * \param [in] famArr - the array of the family field.
5295 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5296 * \throw If \a famArr has an invalid size.
5298 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5300 if(meshDimRelToMaxExt==1)
5307 DataArrayDouble *coo(_coords);
5309 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5310 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5311 _fam_coords.takeRef(famArr);
5314 if(meshDimRelToMaxExt>1)
5315 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5316 int traducedRk=-meshDimRelToMaxExt;
5317 if(traducedRk>=(int)_ms.size())
5318 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5319 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5320 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5321 return _ms[traducedRk]->setFamilyArr(famArr);
5325 * Sets the optional numbers of mesh entities of a given dimension.
5326 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5327 * \param [in] renumArr - the array of the numbers.
5328 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5329 * \throw If \a renumArr has an invalid size.
5331 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5333 if(meshDimRelToMaxExt==1)
5337 _num_coords.nullify();
5338 _rev_num_coords.nullify();
5341 if(_coords.isNull())
5342 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5343 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5344 _num_coords.takeRef(renumArr);
5348 if(meshDimRelToMaxExt>1)
5349 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5350 int traducedRk=-meshDimRelToMaxExt;
5351 if(traducedRk>=(int)_ms.size())
5352 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5353 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5354 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5355 return _ms[traducedRk]->setRenumArr(renumArr);
5359 * Sets the optional names of mesh entities of a given dimension.
5360 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5361 * \param [in] nameArr - the array of the names.
5362 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5363 * \throw If \a nameArr has an invalid size.
5365 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5367 if(meshDimRelToMaxExt==1)
5374 DataArrayDouble *coo(_coords);
5376 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5377 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5378 _name_coords.takeRef(nameArr);
5381 if(meshDimRelToMaxExt>1)
5382 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5383 int traducedRk=-meshDimRelToMaxExt;
5384 if(traducedRk>=(int)_ms.size())
5385 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5386 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5387 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5388 return _ms[traducedRk]->setNameArr(nameArr);
5391 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5393 if(meshDimRelToMaxExt!=1)
5394 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5396 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5397 _global_num_coords.takeRef(globalNumArr);
5400 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5402 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5403 if((const MEDFileUMeshSplitL1 *)(*it))
5404 (*it)->synchronizeTinyInfo(*this);
5408 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5410 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5412 DataArrayInt *arr=_fam_coords;
5414 arr->changeValue(oldId,newId);
5415 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5417 MEDFileUMeshSplitL1 *sp=(*it);
5420 sp->changeFamilyIdArr(oldId,newId);
5425 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5427 std::list< MCAuto<DataArrayInt> > ret;
5428 const DataArrayInt *da(_fam_coords);
5430 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5431 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5433 const MEDFileUMeshSplitL1 *elt(*it);
5436 da=elt->getFamilyField();
5438 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5444 void MEDFileUMesh::computeRevNum() const
5446 if(_num_coords.isNotNull())
5449 int maxValue=_num_coords->getMaxValue(pos);
5450 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5454 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5456 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5459 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5461 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5462 ret.push_back((const DataArrayInt *)_fam_nodes);
5463 ret.push_back((const DataArrayInt *)_num_nodes);
5464 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5465 ret.push_back((const DataArrayInt *)_fam_cells);
5466 ret.push_back((const DataArrayInt *)_num_cells);
5467 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5468 ret.push_back((const DataArrayInt *)_fam_faces);
5469 ret.push_back((const DataArrayInt *)_num_faces);
5470 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5471 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5472 ret.push_back((const DataArrayInt *)_rev_num_cells);
5473 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5477 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5479 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5480 if((const DataArrayInt *)_fam_nodes)
5482 int val=_fam_nodes->getMaxValue(tmp);
5483 ret=std::max(ret,std::abs(val));
5485 if((const DataArrayInt *)_fam_cells)
5487 int val=_fam_cells->getMaxValue(tmp);
5488 ret=std::max(ret,std::abs(val));
5490 if((const DataArrayInt *)_fam_faces)
5492 int val=_fam_faces->getMaxValue(tmp);
5493 ret=std::max(ret,std::abs(val));
5498 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5500 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5501 if((const DataArrayInt *)_fam_nodes)
5503 int val=_fam_nodes->getMaxValue(tmp);
5504 ret=std::max(ret,val);
5506 if((const DataArrayInt *)_fam_cells)
5508 int val=_fam_cells->getMaxValue(tmp);
5509 ret=std::max(ret,val);
5511 if((const DataArrayInt *)_fam_faces)
5513 int val=_fam_faces->getMaxValue(tmp);
5514 ret=std::max(ret,val);
5519 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5521 int ret=std::numeric_limits<int>::max(),tmp=-1;
5522 if((const DataArrayInt *)_fam_nodes)
5524 int val=_fam_nodes->getMinValue(tmp);
5525 ret=std::min(ret,val);
5527 if((const DataArrayInt *)_fam_cells)
5529 int val=_fam_cells->getMinValue(tmp);
5530 ret=std::min(ret,val);
5532 if((const DataArrayInt *)_fam_faces)
5534 int val=_fam_faces->getMinValue(tmp);
5535 ret=std::min(ret,val);
5540 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5542 if(!MEDFileMesh::isEqual(other,eps,what))
5544 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5547 what="Mesh types differ ! This is structured and other is NOT !";
5550 const DataArrayInt *famc1=_fam_nodes;
5551 const DataArrayInt *famc2=otherC->_fam_nodes;
5552 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5554 what="Mismatch of families arr on nodes ! One is defined and not other !";
5559 bool ret=famc1->isEqual(*famc2);
5562 what="Families arr on nodes differ !";
5567 famc2=otherC->_fam_cells;
5568 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5570 what="Mismatch of families arr on cells ! One is defined and not other !";
5575 bool ret=famc1->isEqual(*famc2);
5578 what="Families arr on cells differ !";
5583 famc2=otherC->_fam_faces;
5584 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5586 what="Mismatch of families arr on faces ! One is defined and not other !";
5591 bool ret=famc1->isEqual(*famc2);
5594 what="Families arr on faces differ !";
5599 famc2=otherC->_num_nodes;
5600 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5602 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5607 bool ret=famc1->isEqual(*famc2);
5610 what="Numbering arr on nodes differ !";
5615 famc2=otherC->_num_cells;
5616 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5618 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5623 bool ret=famc1->isEqual(*famc2);
5626 what="Numbering arr on cells differ !";
5631 famc2=otherC->_num_faces;
5632 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5634 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5639 bool ret=famc1->isEqual(*famc2);
5642 what="Numbering arr on faces differ !";
5646 const DataArrayAsciiChar *d1=_names_cells;
5647 const DataArrayAsciiChar *d2=otherC->_names_cells;
5648 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5650 what="Mismatch of naming arr on cells ! One is defined and not other !";
5655 bool ret=d1->isEqual(*d2);
5658 what="Naming arr on cells differ !";
5663 d2=otherC->_names_faces;
5664 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5666 what="Mismatch of naming arr on faces ! One is defined and not other !";
5671 bool ret=d1->isEqual(*d2);
5674 what="Naming arr on faces differ !";
5679 d2=otherC->_names_nodes;
5680 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5682 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5687 bool ret=d1->isEqual(*d2);
5690 what="Naming arr on nodes differ !";
5697 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5699 MEDFileMesh::clearNonDiscrAttributes();
5700 const DataArrayInt *tmp=_fam_nodes;
5702 (const_cast<DataArrayInt *>(tmp))->setName("");
5705 (const_cast<DataArrayInt *>(tmp))->setName("");
5708 (const_cast<DataArrayInt *>(tmp))->setName("");
5711 (const_cast<DataArrayInt *>(tmp))->setName("");
5714 (const_cast<DataArrayInt *>(tmp))->setName("");
5717 (const_cast<DataArrayInt *>(tmp))->setName("");
5721 * Returns ids of mesh entities contained in given families of a given dimension.
5722 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5724 * \param [in] fams - the names of the families of interest.
5725 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5726 * returned instead of ids.
5727 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5728 * numbers, if available and required, of mesh entities of the families. The caller
5729 * is to delete this array using decrRef() as it is no more needed.
5730 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5732 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5734 std::vector<int> famIds(getFamiliesIds(fams));
5735 switch(meshDimRelToMaxExt)
5739 if((const DataArrayInt *)_fam_nodes)
5741 MCAuto<DataArrayInt> da;
5743 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5745 da=_fam_nodes->findIdsEqualList(0,0);
5747 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5752 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5757 if((const DataArrayInt *)_fam_cells)
5759 MCAuto<DataArrayInt> da;
5761 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5763 da=_fam_cells->findIdsEqualList(0,0);
5765 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5770 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5775 if((const DataArrayInt *)_fam_faces)
5777 MCAuto<DataArrayInt> da;
5779 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5781 da=_fam_faces->findIdsEqualList(0,0);
5783 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5788 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5792 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5794 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5798 * Sets the family field of a given relative dimension.
5799 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5800 * the family field is set.
5801 * \param [in] famArr - the array of the family field.
5802 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5803 * \throw If \a famArr has an invalid size.
5804 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5806 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5808 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5810 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5811 switch(meshDimRelToMaxExt)
5815 int nbCells(mesh->getNumberOfCells());
5817 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5823 int nbNodes(mesh->getNumberOfNodes());
5825 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5831 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5833 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5838 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5845 * Sets the optional numbers of mesh entities of a given dimension.
5846 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5847 * \param [in] renumArr - the array of the numbers.
5848 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5849 * \throw If \a renumArr has an invalid size.
5850 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5852 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5854 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5856 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5857 switch(meshDimRelToMaxExt)
5861 int nbCells=mesh->getNumberOfCells();
5862 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5863 _num_cells=renumArr;
5868 int nbNodes=mesh->getNumberOfNodes();
5869 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5870 _num_nodes=renumArr;
5875 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5876 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5877 _num_faces=renumArr;
5881 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5884 renumArr->incrRef();
5888 * Sets the optional names of mesh entities of a given dimension.
5889 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5890 * \param [in] nameArr - the array of the names.
5891 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5892 * \throw If \a nameArr has an invalid size.
5894 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5896 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5898 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5899 switch(meshDimRelToMaxExt)
5903 int nbCells=mesh->getNumberOfCells();
5904 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5905 _names_cells=nameArr;
5910 int nbNodes=mesh->getNumberOfNodes();
5911 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5912 _names_nodes=nameArr;
5917 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5918 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5919 _names_faces=nameArr;
5922 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5928 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5930 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
5934 * Adds a group of nodes to \a this mesh.
5935 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5936 * The ids should be sorted and different each other (MED file norm).
5938 * \warning this method can alter default "FAMILLE_ZERO" family.
5939 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5941 * \throw If the node coordinates array is not set.
5942 * \throw If \a ids == \c NULL.
5943 * \throw If \a ids->getName() == "".
5944 * \throw If \a ids does not respect the MED file norm.
5945 * \throw If a group with name \a ids->getName() already exists.
5947 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5953 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5955 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5956 * The ids should be sorted and different each other (MED file norm).
5958 * \warning this method can alter default "FAMILLE_ZERO" family.
5959 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5961 * \throw If the node coordinates array is not set.
5962 * \throw If \a ids == \c NULL.
5963 * \throw If \a ids->getName() == "".
5964 * \throw If \a ids does not respect the MED file norm.
5965 * \throw If a group with name \a ids->getName() already exists.
5967 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5969 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5970 addGroupUnderground(false,ids,fam);
5975 * Returns the family field for mesh entities of a given dimension.
5976 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5977 * \return const DataArrayInt * - the family field. It is an array of ids of families
5978 * each mesh entity belongs to. It can be \c NULL.
5979 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5981 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5983 switch(meshDimRelToMaxExt)
5992 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5997 * Returns the family field for mesh entities of a given dimension.
5998 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5999 * \return const DataArrayInt * - the family field. It is an array of ids of families
6000 * each mesh entity belongs to. It can be \c NULL.
6001 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6003 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
6005 switch(meshDimRelToMaxExt)
6014 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6019 * Returns the optional numbers of mesh entities of a given dimension.
6020 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6021 * \return const DataArrayInt * - the array of the entity numbers.
6022 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6023 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6025 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
6027 switch(meshDimRelToMaxExt)
6036 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6041 * Returns the optional numbers of mesh entities of a given dimension transformed using
6042 * DataArrayInt::invertArrayN2O2O2N().
6043 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6044 * \return const DataArrayInt * - the array of the entity numbers transformed using
6045 * DataArrayInt::invertArrayN2O2O2N().
6046 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6047 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6049 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
6051 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
6052 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
6053 if(meshDimRelToMaxExt==0)
6055 if((const DataArrayInt *)_num_cells)
6058 int maxValue=_num_cells->getMaxValue(pos);
6059 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
6060 return _rev_num_cells;
6063 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
6067 if((const DataArrayInt *)_num_nodes)
6070 int maxValue=_num_nodes->getMaxValue(pos);
6071 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
6072 return _rev_num_nodes;
6075 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6079 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6081 switch(meshDimRelToMaxExt)
6084 return _names_cells;
6086 return _names_nodes;
6088 return _names_faces;
6090 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6094 MCAuto<DataArrayInt> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6096 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6100 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6101 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6103 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6105 std::vector<int> ret(1);
6110 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6111 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6113 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6115 std::vector<int> ret(2);
6121 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6123 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6125 std::vector<int> ret;
6126 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6137 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6139 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6141 std::vector<int> ret;
6142 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6153 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6155 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6157 std::vector<int> ret;
6158 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6169 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6171 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
6173 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6177 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
6179 DataArrayInt *arr=_fam_nodes;
6181 arr->changeValue(oldId,newId);
6184 arr->changeValue(oldId,newId);
6187 arr->changeValue(oldId,newId);
6190 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6192 std::list< MCAuto<DataArrayInt> > ret;
6193 const DataArrayInt *da(_fam_nodes);
6195 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6198 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6201 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6205 void MEDFileStructuredMesh::deepCpyAttributes()
6207 if((const DataArrayInt*)_fam_nodes)
6208 _fam_nodes=_fam_nodes->deepCopy();
6209 if((const DataArrayInt*)_num_nodes)
6210 _num_nodes=_num_nodes->deepCopy();
6211 if((const DataArrayAsciiChar*)_names_nodes)
6212 _names_nodes=_names_nodes->deepCopy();
6213 if((const DataArrayInt*)_fam_cells)
6214 _fam_cells=_fam_cells->deepCopy();
6215 if((const DataArrayInt*)_num_cells)
6216 _num_cells=_num_cells->deepCopy();
6217 if((const DataArrayAsciiChar*)_names_cells)
6218 _names_cells=_names_cells->deepCopy();
6219 if((const DataArrayInt*)_fam_faces)
6220 _fam_faces=_fam_faces->deepCopy();
6221 if((const DataArrayInt*)_num_faces)
6222 _num_faces=_num_faces->deepCopy();
6223 if((const DataArrayAsciiChar*)_names_faces)
6224 _names_faces=_names_faces->deepCopy();
6225 if((const DataArrayInt*)_rev_num_nodes)
6226 _rev_num_nodes=_rev_num_nodes->deepCopy();
6227 if((const DataArrayInt*)_rev_num_cells)
6228 _rev_num_cells=_rev_num_cells->deepCopy();
6232 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6234 * \return a pointer to cartesian mesh that need to be managed by the caller.
6235 * \warning the returned pointer has to be managed by the caller.
6239 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6240 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6241 * \param [in] renum - it must be \c false.
6242 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6243 * delete using decrRef() as it is no more needed.
6245 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6249 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6250 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6251 switch(meshDimRelToMax)
6257 return const_cast<MEDCouplingStructuredMesh *>(m);
6262 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6263 buildMinusOneImplicitPartIfNeeded();
6264 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6270 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6274 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6276 std::vector<int> ret;
6277 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6278 if(famCells && famCells->presenceOfValue(ret))
6280 if(famFaces && famFaces->presenceOfValue(ret))
6285 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6287 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6288 const DataArrayInt *famNodes(_fam_nodes);
6289 if(famNodes && famNodes->presenceOfValue(ret))
6295 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6296 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6297 * \return int - the number of entities.
6298 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6300 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6302 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6304 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6305 switch(meshDimRelToMaxExt)
6308 return cmesh->getNumberOfCells();
6310 return cmesh->getNumberOfNodes();
6312 return cmesh->getNumberOfCellsOfSubLevelMesh();
6314 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6318 int MEDFileStructuredMesh::getNumberOfNodes() const
6320 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6322 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6323 return cmesh->getNumberOfNodes();
6326 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6328 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6330 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6331 switch(meshDimRelToMaxExt)
6334 return cmesh->getNumberOfCells();
6336 return cmesh->getNumberOfCellsOfSubLevelMesh();
6338 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6342 bool MEDFileStructuredMesh::hasImplicitPart() const
6348 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6350 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6352 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6353 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6356 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6357 if(cm.getReverseExtrudedType()!=gt)
6358 throw INTERP_KERNEL::Exception(MSG);
6359 buildImplicitPart();
6360 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6364 if(gt!=zeFaceMesh->getCellModelEnum())
6365 throw INTERP_KERNEL::Exception(MSG);
6366 return zeFaceMesh->getNumberOfCells();
6370 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6372 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6374 buildImplicitPart();
6377 void MEDFileStructuredMesh::buildImplicitPart() const
6379 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6381 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6382 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6385 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6387 _faces_if_necessary=0;
6391 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6392 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6394 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6396 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6399 return _faces_if_necessary;
6402 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6404 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6406 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6407 switch(meshDimRelToMax)
6411 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6416 int mdim(cmesh->getMeshDimension());
6418 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6419 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6423 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6427 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6429 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6432 return getNumberOfCellsAtLevel(0);
6435 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6437 if(st.getNumberOfItems()!=1)
6438 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 !");
6439 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6440 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6441 if(getNumberOfNodes()!=(int)nodesFetched.size())
6442 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6443 if(st[0].getPflName().empty())
6445 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6448 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6449 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6450 int sz(nodesFetched.size());
6451 for(const int *work=arr->begin();work!=arr->end();work++)
6453 std::vector<int> conn;
6454 cmesh->getNodeIdsOfCell(*work,conn);
6455 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6456 if(*it>=0 && *it<sz)
6457 nodesFetched[*it]=true;
6459 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6463 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6465 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6469 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6470 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6472 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6473 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6475 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6478 if(!mrs || mrs->isCellFamilyFieldReading())
6480 famCells=DataArrayInt::New();
6481 famCells->alloc(nbOfElt,1);
6482 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6485 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6488 if(!mrs || mrs->isCellNumFieldReading())
6490 numCells=DataArrayInt::New();
6491 numCells->alloc(nbOfElt,1);
6492 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6495 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6498 if(!mrs || mrs->isCellNameFieldReading())
6500 namesCells=DataArrayAsciiChar::New();
6501 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6502 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6503 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6508 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6510 setName(strm->getName());
6511 setDescription(strm->getDescription());
6512 setUnivName(strm->getUnivName());
6513 setIteration(strm->getIteration());
6514 setOrder(strm->getOrder());
6515 setTimeValue(strm->getTime());
6516 setTimeUnit(strm->getTimeUnit());
6517 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6518 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6519 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6522 if(!mrs || mrs->isNodeFamilyFieldReading())
6524 int nbNodes(getNumberOfNodes());
6526 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6527 _fam_nodes=DataArrayInt::New();
6528 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6529 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...
6530 _fam_nodes->fillWithZero();
6531 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6534 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6537 if(!mrs || mrs->isNodeNumFieldReading())
6539 _num_nodes=DataArrayInt::New();
6540 _num_nodes->alloc(nbOfElt,1);
6541 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6544 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6547 if(!mrs || mrs->isNodeNameFieldReading())
6549 _names_nodes=DataArrayAsciiChar::New();
6550 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6551 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6552 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6555 int meshDim(getStructuredMesh()->getMeshDimension());
6556 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6558 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6561 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6563 int meshDim(getStructuredMesh()->getMeshDimension());
6564 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6566 if((const DataArrayInt *)_fam_cells)
6567 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6568 if((const DataArrayInt *)_fam_faces)
6569 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6570 if((const DataArrayInt *)_fam_nodes)
6571 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6572 if((const DataArrayInt *)_num_cells)
6573 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6574 if((const DataArrayInt *)_num_faces)
6575 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6576 if((const DataArrayInt *)_num_nodes)
6577 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6578 if((const DataArrayAsciiChar *)_names_cells)
6580 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6582 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6583 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6584 throw INTERP_KERNEL::Exception(oss.str().c_str());
6586 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6588 if((const DataArrayAsciiChar *)_names_faces)
6590 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6592 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6593 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6594 throw INTERP_KERNEL::Exception(oss.str().c_str());
6596 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6598 if((const DataArrayAsciiChar *)_names_nodes)
6600 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6602 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6603 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6604 throw INTERP_KERNEL::Exception(oss.str().c_str());
6606 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6609 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6613 * Returns an empty instance of MEDFileCMesh.
6614 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6615 * mesh using decrRef() as it is no more needed.
6617 MEDFileCMesh *MEDFileCMesh::New()
6619 return new MEDFileCMesh;
6623 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6624 * file. The first mesh in the file is loaded.
6625 * \param [in] fileName - the name of MED file to read.
6626 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6627 * mesh using decrRef() as it is no more needed.
6628 * \throw If the file is not readable.
6629 * \throw If there is no meshes in the file.
6630 * \throw If the mesh in the file is not a Cartesian one.
6632 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6634 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6635 return New(fid,mrs);
6638 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6640 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6644 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6645 * file. The mesh to load is specified by its name and numbers of a time step and an
6647 * \param [in] fileName - the name of MED file to read.
6648 * \param [in] mName - the name of the mesh to read.
6649 * \param [in] dt - the number of a time step.
6650 * \param [in] it - the number of an iteration.
6651 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6652 * mesh using decrRef() as it is no more needed.
6653 * \throw If the file is not readable.
6654 * \throw If there is no mesh with given attributes in the file.
6655 * \throw If the mesh in the file is not a Cartesian one.
6657 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6659 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6660 return New(fid,mName,dt,it,mrs);
6663 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6665 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6668 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6670 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6673 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6675 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6676 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6681 * Returns the dimension on cells in \a this mesh.
6682 * \return int - the mesh dimension.
6683 * \throw If there are no cells in this mesh.
6685 int MEDFileCMesh::getMeshDimension() const
6687 if(!((const MEDCouplingCMesh*)_cmesh))
6688 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6689 return _cmesh->getMeshDimension();
6693 * Returns the dimension on nodes in \a this mesh.
6694 * \return int - the space dimension.
6695 * \throw If there are no cells in this mesh.
6697 int MEDFileCMesh::getSpaceDimension() const
6699 if(!((const MEDCouplingCMesh*)_cmesh))
6700 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6701 return _cmesh->getSpaceDimension();
6705 * Returns a string describing \a this mesh.
6706 * \return std::string - the mesh information string.
6708 std::string MEDFileCMesh::simpleRepr() const
6710 return MEDFileStructuredMesh::simpleRepr();
6714 * Returns a full textual description of \a this mesh.
6715 * \return std::string - the string holding the mesh description.
6717 std::string MEDFileCMesh::advancedRepr() const
6719 return simpleRepr();
6722 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6724 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6728 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6730 return new MEDFileCMesh;
6733 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6735 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6736 ret->deepCpyEquivalences(*this);
6737 if((const MEDCouplingCMesh*)_cmesh)
6738 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6739 ret->deepCpyAttributes();
6744 * Checks if \a this and another mesh are equal.
6745 * \param [in] other - the mesh to compare with.
6746 * \param [in] eps - a precision used to compare real values.
6747 * \param [in,out] what - the string returning description of unequal data.
6748 * \return bool - \c true if the meshes are equal, \c false, else.
6750 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6752 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6754 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6757 what="Mesh types differ ! This is cartesian and other is NOT !";
6760 clearNonDiscrAttributes();
6761 otherC->clearNonDiscrAttributes();
6762 const MEDCouplingCMesh *coo1=_cmesh;
6763 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6764 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6766 what="Mismatch of cartesian meshes ! One is defined and not other !";
6771 bool ret=coo1->isEqual(coo2,eps);
6774 what="cartesian meshes differ !";
6782 * Clears redundant attributes of incorporated data arrays.
6784 void MEDFileCMesh::clearNonDiscrAttributes() const
6786 MEDFileStructuredMesh::clearNonDiscrAttributes();
6787 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6790 MEDFileCMesh::MEDFileCMesh()
6794 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6797 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6799 catch(INTERP_KERNEL::Exception& e)
6804 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6806 MEDCoupling::MEDCouplingMeshType meshType;
6809 MEDCoupling::MEDCouplingAxisType axType;
6810 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6811 if(meshType!=CARTESIAN)
6813 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6814 throw INTERP_KERNEL::Exception(oss.str().c_str());
6816 MEDFileCMeshL2 loaderl2;
6817 loaderl2.loadAll(fid,mid,mName,dt,it);
6818 setAxisType(axType);
6819 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6822 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6826 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6827 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6829 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6831 synchronizeTinyInfoOnLeaves();
6835 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6837 synchronizeTinyInfoOnLeaves();
6842 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6843 * \param [in] m - the new MEDCouplingCMesh to refer to.
6844 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6847 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6849 dealWithTinyInfo(m);
6855 MEDFileMesh *MEDFileCMesh::cartesianize() const
6857 if(getAxisType()==AX_CART)
6860 return const_cast<MEDFileCMesh *>(this);
6864 const MEDCouplingCMesh *cmesh(getMesh());
6866 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6867 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6868 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6869 clmesh->setCoords(coords);
6870 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6871 ret->MEDFileStructuredMesh::operator=(*this);
6872 ret->setMesh(clmesh);
6873 ret->setAxisType(AX_CART);
6878 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6880 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6881 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6882 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6883 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6884 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6885 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6886 int spaceDim(_cmesh->getSpaceDimension());
6887 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6888 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6889 for(int i=0;i<spaceDim;i++)
6891 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6893 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6894 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
6895 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
6897 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6899 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6900 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6901 for(int i=0;i<spaceDim;i++)
6903 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6904 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6907 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6908 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6911 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6913 const MEDCouplingCMesh *cmesh=_cmesh;
6916 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6917 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6918 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6919 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6922 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6924 return new MEDFileCurveLinearMesh;
6927 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6929 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6932 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6934 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6935 return New(fid,mrs);
6938 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6940 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6941 return New(fid,mName,dt,it,mrs);
6944 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6946 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6949 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6951 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6954 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6956 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6957 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6961 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6963 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6967 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6969 return new MEDFileCurveLinearMesh;
6972 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6974 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6975 ret->deepCpyEquivalences(*this);
6976 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6977 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6978 ret->deepCpyAttributes();
6982 int MEDFileCurveLinearMesh::getMeshDimension() const
6984 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6985 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6986 return _clmesh->getMeshDimension();
6989 std::string MEDFileCurveLinearMesh::simpleRepr() const
6991 return MEDFileStructuredMesh::simpleRepr();
6994 std::string MEDFileCurveLinearMesh::advancedRepr() const
6996 return simpleRepr();
6999 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7001 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7003 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
7006 what="Mesh types differ ! This is curve linear and other is NOT !";
7009 clearNonDiscrAttributes();
7010 otherC->clearNonDiscrAttributes();
7011 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
7012 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
7013 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7015 what="Mismatch of curve linear meshes ! One is defined and not other !";
7020 bool ret=coo1->isEqual(coo2,eps);
7023 what="curve linear meshes differ !";
7030 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
7032 MEDFileStructuredMesh::clearNonDiscrAttributes();
7033 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
7036 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
7038 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
7041 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
7042 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
7043 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
7044 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
7047 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
7049 synchronizeTinyInfoOnLeaves();
7053 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
7055 dealWithTinyInfo(m);
7061 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
7063 if(getAxisType()==AX_CART)
7066 return const_cast<MEDFileCurveLinearMesh *>(this);
7070 const MEDCouplingCurveLinearMesh *mesh(getMesh());
7072 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7073 const DataArrayDouble *coords(mesh->getCoords());
7075 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
7076 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7077 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
7078 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7079 mesh2->setCoords(coordsCart);
7080 ret->setMesh(mesh2);
7081 ret->setAxisType(AX_CART);
7086 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7088 synchronizeTinyInfoOnLeaves();
7092 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7096 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7099 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7101 catch(INTERP_KERNEL::Exception& e)
7106 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7108 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7109 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7110 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7111 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7112 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7113 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7114 int spaceDim=_clmesh->getSpaceDimension();
7115 int meshDim=_clmesh->getMeshDimension();
7116 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7117 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7118 const DataArrayDouble *coords=_clmesh->getCoords();
7120 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7121 for(int i=0;i<spaceDim;i++)
7123 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7125 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7126 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
7127 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
7129 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7131 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7132 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7133 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
7134 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
7136 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
7138 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7139 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7142 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7144 MEDCoupling::MEDCouplingMeshType meshType;
7147 MEDCoupling::MEDCouplingAxisType axType;
7148 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7149 setAxisType(axType);
7150 if(meshType!=CURVE_LINEAR)
7152 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7153 throw INTERP_KERNEL::Exception(oss.str().c_str());
7155 MEDFileCLMeshL2 loaderl2;
7156 loaderl2.loadAll(fid,mid,mName,dt,it);
7157 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7160 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7163 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7165 return new MEDFileMeshMultiTS;
7168 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7170 return new MEDFileMeshMultiTS(fid);
7173 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7175 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7179 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7181 return new MEDFileMeshMultiTS(fid,mName);
7184 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7186 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7187 return New(fid,mName);
7190 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7192 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7193 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7195 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7196 if((const MEDFileMesh *)*it)
7197 meshOneTs[i]=(*it)->deepCopy();
7198 ret->_mesh_one_ts=meshOneTs;
7202 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7204 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7207 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7209 std::vector<const BigMemoryObject *> ret;
7210 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7211 ret.push_back((const MEDFileMesh *)*it);
7215 std::string MEDFileMeshMultiTS::getName() const
7217 if(_mesh_one_ts.empty())
7218 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7219 return _mesh_one_ts[0]->getName();
7222 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7224 std::string oldName(getName());
7225 std::vector< std::pair<std::string,std::string> > v(1);
7226 v[0].first=oldName; v[0].second=newMeshName;
7230 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7233 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7235 MEDFileMesh *cur(*it);
7237 ret=cur->changeNames(modifTab) || ret;
7242 void MEDFileMeshMultiTS::cartesianizeMe()
7244 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7246 MEDFileMesh *cur(*it);
7249 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7255 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7257 if(_mesh_one_ts.empty())
7258 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7259 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7262 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7265 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7266 _mesh_one_ts.resize(1);
7267 mesh1TimeStep->incrRef();
7268 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7269 _mesh_one_ts[0]=mesh1TimeStep;
7272 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7274 if ( MEDFileMesh* m = getOneTimeStep() )
7275 return m->getJoints();
7280 * \brief Set Joints that are common to all time-stamps
7282 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7284 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7286 (*it)->setJoints( joints );
7290 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7292 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7293 if((*it).isNotNull())
7294 if((*it)->presenceOfStructureElements())
7299 void MEDFileMeshMultiTS::killStructureElements()
7301 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7302 if((*it).isNotNull())
7303 (*it)->killStructureElements();
7306 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7308 MEDFileJoints *joints(getJoints());
7309 bool jointsWritten(false);
7311 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7313 if ( jointsWritten )
7314 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7316 jointsWritten = true;
7318 (*it)->copyOptionsFrom(*this);
7319 (*it)->writeLL(fid);
7322 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7325 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7327 MEDFileJoints *joints(0);
7328 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7330 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7331 joints = getOneTimeStep()->getJoints();
7333 _mesh_one_ts.clear(); //for the moment to be improved
7334 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7337 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7341 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7344 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7347 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7348 throw INTERP_KERNEL::Exception(oss.str().c_str());
7351 MEDCoupling::MEDCouplingMeshType meshType;
7353 MEDCoupling::MEDCouplingAxisType dummy3;
7354 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7355 loadFromFile(fid,ms.front());
7357 catch(INTERP_KERNEL::Exception& e)
7362 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7365 loadFromFile(fid,mName);
7367 catch(INTERP_KERNEL::Exception& e)
7372 MEDFileMeshes *MEDFileMeshes::New()
7374 return new MEDFileMeshes;
7377 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7379 return new MEDFileMeshes(fid);
7382 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7384 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7388 void MEDFileMeshes::writeLL(med_idt fid) const
7390 checkConsistencyLight();
7391 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7393 (*it)->copyOptionsFrom(*this);
7394 (*it)->writeLL(fid);
7398 // MEDFileMeshes::writ checkConsistencyLight();
7400 int MEDFileMeshes::getNumberOfMeshes() const
7402 return _meshes.size();
7405 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7407 return new MEDFileMeshesIterator(this);
7410 /** Return a borrowed reference (caller is not responsible) */
7411 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7413 if(i<0 || i>=(int)_meshes.size())
7415 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7416 throw INTERP_KERNEL::Exception(oss.str().c_str());
7418 return _meshes[i]->getOneTimeStep();
7421 /** Return a borrowed reference (caller is not responsible) */
7422 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7424 std::vector<std::string> ms=getMeshesNames();
7425 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7428 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7429 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7430 throw INTERP_KERNEL::Exception(oss.str().c_str());
7432 return getMeshAtPos((int)std::distance(ms.begin(),it));
7435 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7437 std::vector<std::string> ret(_meshes.size());
7439 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7441 const MEDFileMeshMultiTS *f=(*it);
7444 ret[i]=f->getName();
7448 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7449 throw INTERP_KERNEL::Exception(oss.str().c_str());
7455 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7458 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7460 MEDFileMeshMultiTS *cur(*it);
7462 ret=cur->changeNames(modifTab) || ret;
7467 void MEDFileMeshes::cartesianizeMe()
7469 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7471 MEDFileMeshMultiTS *cur(*it);
7473 cur->cartesianizeMe();
7477 void MEDFileMeshes::resize(int newSize)
7479 _meshes.resize(newSize);
7482 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7485 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7486 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7487 elt->setOneTimeStep(mesh);
7488 _meshes.push_back(elt);
7491 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7494 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7495 if(i>=(int)_meshes.size())
7496 _meshes.resize(i+1);
7497 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7498 elt->setOneTimeStep(mesh);
7502 void MEDFileMeshes::destroyMeshAtPos(int i)
7504 if(i<0 || i>=(int)_meshes.size())
7506 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7507 throw INTERP_KERNEL::Exception(oss.str().c_str());
7509 _meshes.erase(_meshes.begin()+i);
7512 void MEDFileMeshes::loadFromFile(med_idt fid)
7514 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7516 _meshes.resize(ms.size());
7517 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7518 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7521 MEDFileMeshes::MEDFileMeshes()
7525 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7530 catch(INTERP_KERNEL::Exception& /*e*/)
7534 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7536 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7538 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7539 if((const MEDFileMeshMultiTS *)*it)
7540 meshes[i]=(*it)->deepCopy();
7541 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7542 ret->_meshes=meshes;
7546 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7548 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7551 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7553 std::vector<const BigMemoryObject *> ret;
7554 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7555 ret.push_back((const MEDFileMeshMultiTS *)*it);
7559 std::string MEDFileMeshes::simpleRepr() const
7561 std::ostringstream oss;
7562 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7563 simpleReprWithoutHeader(oss);
7567 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7569 int nbOfMeshes=getNumberOfMeshes();
7570 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7571 std::vector<std::string> mns=getMeshesNames();
7572 for(int i=0;i<nbOfMeshes;i++)
7573 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7576 void MEDFileMeshes::checkConsistencyLight() const
7578 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7580 std::set<std::string> s;
7581 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7583 const MEDFileMeshMultiTS *elt=(*it);
7586 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7587 throw INTERP_KERNEL::Exception(oss.str().c_str());
7589 std::size_t sz=s.size();
7590 s.insert(std::string((*it)->getName()));
7593 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7594 throw INTERP_KERNEL::Exception(oss.str().c_str());
7599 bool MEDFileMeshes::presenceOfStructureElements() const
7601 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7602 if((*it).isNotNull())
7603 if((*it)->presenceOfStructureElements())
7608 void MEDFileMeshes::killStructureElements()
7610 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7611 if((*it).isNotNull())
7612 (*it)->killStructureElements();
7615 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7620 _nb_iter=ms->getNumberOfMeshes();
7624 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7628 MEDFileMesh *MEDFileMeshesIterator::nextt()
7630 if(_iter_id<_nb_iter)
7632 MEDFileMeshes *ms(_ms);
7634 return ms->getMeshAtPos(_iter_id++);
7642 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7644 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7645 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7647 if(geoType==MED_NO_GEOTYPE)
7648 return INTERP_KERNEL::NORM_ERROR;
7649 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7650 throw INTERP_KERNEL::Exception(oss.str());
7652 return typmai2[std::distance(typmai,pos)];
7655 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7665 std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7666 throw INTERP_KERNEL::Exception(oss.str());