1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileFieldOverView.hxx"
23 #include "MEDFileField.hxx"
24 #include "MEDLoader.hxx"
25 #include "MEDLoaderNS.hxx"
26 #include "MEDFileSafeCaller.txx"
27 #include "MEDLoaderBase.hxx"
29 #include "MEDCouplingUMesh.hxx"
30 #include "MEDCouplingMappedExtrudedMesh.hxx"
32 #include "InterpKernelAutoPtr.hxx"
37 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
38 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
39 extern med_geometry_type typmai3[34];
41 using namespace MEDCoupling;
43 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
45 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
47 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
51 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
53 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
54 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
56 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
57 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
58 ret+=(*it2).capacity();
60 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
61 ret+=(*it).first.capacity()+sizeof(int);
65 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
67 std::vector<const BigMemoryObject *> ret(1);
68 ret[0]=(const MEDFileEquivalences *)_equiv;
73 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
74 * file. The first mesh in the file is loaded.
75 * \param [in] fileName - the name of MED file to read.
76 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
77 * mesh using decrRef() as it is no more needed.
78 * \throw If the file is not readable.
79 * \throw If there is no meshes in the file.
80 * \throw If the mesh in the file is of a not supported type.
82 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
84 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
88 MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
90 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
93 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
94 throw INTERP_KERNEL::Exception(oss.str().c_str());
96 MEDCoupling::MEDCouplingMeshType meshType;
99 MEDCoupling::MEDCouplingAxisType dummy3;
100 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
101 MCAuto<MEDFileMesh> ret;
106 ret=MEDFileUMesh::New();
111 ret=MEDFileCMesh::New();
116 ret=MEDFileCurveLinearMesh::New();
121 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
122 throw INTERP_KERNEL::Exception(oss.str().c_str());
125 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
130 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
131 * file. The mesh to load is specified by its name and numbers of a time step and an
133 * \param [in] fileName - the name of MED file to read.
134 * \param [in] mName - the name of the mesh to read.
135 * \param [in] dt - the number of a time step.
136 * \param [in] it - the number of an iteration.
137 * \param [in] joints - the sub-domain joints to use instead of those that can be read
138 * from the MED file. Usually this joints are those just read by another iteration
139 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
140 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
141 * mesh using decrRef() as it is no more needed.
142 * \throw If the file is not readable.
143 * \throw If there is no mesh with given attributes in the file.
144 * \throw If the mesh in the file is of a not supported type.
146 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
148 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
149 return New(fid,mName,dt,it,mrs,joints);
152 MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
154 MEDCoupling::MEDCouplingMeshType meshType;
157 MEDCoupling::MEDCouplingAxisType dummy3;
158 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
159 MCAuto<MEDFileMesh> ret;
164 ret=MEDFileUMesh::New();
169 ret=MEDFileCMesh::New();
174 ret=MEDFileCurveLinearMesh::New();
179 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
180 throw INTERP_KERNEL::Exception(oss.str().c_str());
183 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
188 * Writes \a this mesh into an open MED file specified by its descriptor.
189 * \param [in] fid - the MED file descriptor.
190 * \throw If the mesh name is not set.
191 * \throw If the file is open for reading only.
192 * \throw If the writing mode == 1 and the same data is present in an existing file.
194 void MEDFileMesh::writeLL(med_idt fid) const
197 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
199 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
202 const MEDFileEquivalences *eqs(_equiv);
208 * Checks if \a this and another mesh are equal.
209 * \param [in] other - the mesh to compare with.
210 * \param [in] eps - a precision used to compare real values.
211 * \param [in,out] what - the string returning description of unequal data.
212 * \return bool - \c true if the meshes are equal, \c false, else.
214 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
216 if(_order!=other->_order)
218 what="Orders differ !";
221 if(_iteration!=other->_iteration)
223 what="Iterations differ !";
226 if(fabs(_time-other->_time)>eps)
228 what="Time values differ !";
231 if(_dt_unit!=other->_dt_unit)
233 what="Time units differ !";
236 if(_name!=other->_name)
238 what="Names differ !";
241 //univ_name has been ignored -> not a bug because it is a mutable attribute
242 if(_desc_name!=other->_desc_name)
244 what="Description names differ !";
247 if(!areGrpsEqual(other,what))
249 if(!areFamsEqual(other,what))
251 if(!areEquivalencesEqual(other,what))
256 void MEDFileMesh::setName(const std::string& name)
262 * Clears redundant attributes of incorporated data arrays.
264 void MEDFileMesh::clearNonDiscrAttributes() const
269 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
271 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
273 if((*it).first==_name)
283 * Copies data on groups and families from another mesh.
284 * \param [in] other - the mesh to copy the data from.
286 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
288 _groups=other._groups;
289 _families=other._families;
294 * This method clear all the groups in the map.
295 * So this method does not operate at all on arrays.
296 * So this method can lead to orphan families.
298 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
300 void MEDFileMesh::clearGrpMap()
306 * This method clear all the families in the map.
307 * So this method does not operate at all on arrays.
308 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
310 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
312 void MEDFileMesh::clearFamMap()
318 * This method clear all the families and groups in the map.
319 * So this method does not operate at all on arrays.
320 * As all groups and families entry will be removed after
321 * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object.
323 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
325 void MEDFileMesh::clearFamGrpMaps()
332 * Returns names of families constituting a group.
333 * \param [in] name - the name of the group of interest.
334 * \return std::vector<std::string> - a sequence of names of the families.
335 * \throw If the name of a nonexistent group is specified.
337 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
339 std::string oname(name);
340 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
341 if(it==_groups.end())
343 std::vector<std::string> grps=getGroupsNames();
344 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
345 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
346 throw INTERP_KERNEL::Exception(oss.str().c_str());
352 * Returns names of families constituting some groups.
353 * \param [in] grps - a sequence of names of groups of interest.
354 * \return std::vector<std::string> - a sequence of names of the families.
355 * \throw If a name of a nonexistent group is present in \a grps.
357 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
359 std::set<std::string> fams;
360 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
362 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
363 if(it2==_groups.end())
365 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
366 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
367 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
368 throw INTERP_KERNEL::Exception(oss.str().c_str());
370 fams.insert((*it2).second.begin(),(*it2).second.end());
372 std::vector<std::string> fams2(fams.begin(),fams.end());
377 * Returns ids of families constituting a group.
378 * \param [in] name - the name of the group of interest.
379 * \return std::vector<int> - sequence of ids of the families.
380 * \throw If the name of a nonexistent group is specified.
382 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
384 std::string oname(name);
385 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
386 std::vector<std::string> grps=getGroupsNames();
387 if(it==_groups.end())
389 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
390 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
391 throw INTERP_KERNEL::Exception(oss.str().c_str());
393 return getFamiliesIds((*it).second);
397 * Sets names of families constituting a group. If data on families of this group is
398 * already present, it is overwritten. Every family in \a fams is checked, and if a
399 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
400 * \param [in] name - the name of the group of interest.
401 * \param [in] fams - a sequence of names of families constituting the group.
403 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
405 std::string oname(name);
407 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
409 std::map<std::string,int>::iterator it2=_families.find(*it1);
410 if(it2==_families.end())
416 * Sets families constituting a group. The families are specified by their ids.
417 * If a family name is not found by its id, an exception is thrown.
418 * If several families have same id, the first one in lexical order is taken.
419 * \param [in] name - the name of the group of interest.
420 * \param [in] famIds - a sequence of ids of families constituting the group.
421 * \throw If a family name is not found by its id.
423 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
425 std::string oname(name);
426 std::vector<std::string> fams(famIds.size());
428 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
430 std::string name2=getFamilyNameGivenId(*it1);
437 * Returns names of groups including a given family.
438 * \param [in] name - the name of the family of interest.
439 * \return std::vector<std::string> - a sequence of names of groups including the family.
441 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
443 std::vector<std::string> ret;
444 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
446 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
449 ret.push_back((*it1).first);
457 * Adds an existing family to groups.
458 * \param [in] famName - a name of family to add to \a grps.
459 * \param [in] grps - a sequence of group names to add the family in.
460 * \throw If a family named \a famName not yet exists.
462 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
464 std::string fName(famName);
465 const std::map<std::string,int>::const_iterator it=_families.find(fName);
466 if(it==_families.end())
468 std::vector<std::string> fams=getFamiliesNames();
469 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
470 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
471 throw INTERP_KERNEL::Exception(oss.str().c_str());
473 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
475 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
476 if(it2!=_groups.end())
477 (*it2).second.push_back(fName);
480 std::vector<std::string> grps2(1,fName);
487 * Returns names of all groups of \a this mesh.
488 * \return std::vector<std::string> - a sequence of group names.
490 std::vector<std::string> MEDFileMesh::getGroupsNames() const
492 std::vector<std::string> ret(_groups.size());
494 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
500 * Returns names of all families of \a this mesh.
501 * \return std::vector<std::string> - a sequence of family names.
503 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
505 std::vector<std::string> ret(_families.size());
507 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
513 * Returns names of all families of \a this mesh but like they would be in file.
514 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
515 * This method is only useful for aggressive users that want to have in their file a same family lying both on cells and on nodes. This is not a good idea for lisibility !
516 * For your information 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 * \sa MEDFileMesh::removeOrphanFamilies
832 void MEDFileMesh::rearrangeFamilies()
834 checkOrphanFamilyZero();
835 removeFamiliesReferedByNoGroups();
837 std::vector<int> levels(getNonEmptyLevelsExt());
838 std::set<int> idsRefed;
839 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
840 idsRefed.insert((*it).second);
841 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
843 const DataArrayInt *fams(0);
846 fams=getFamilyFieldAtLevel(*it);
848 catch(INTERP_KERNEL::Exception& e) { }
851 std::vector<bool> v(fams->getNumberOfTuples(),false);
852 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
853 fams->switchOnTupleEqualTo(*pt,v);
854 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
855 if(!unfetchedIds->empty())
857 MCAuto<DataArrayInt> newFams(fams->deepCopy());
858 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
859 setFamilyFieldArr(*it,newFams);
862 removeOrphanFamilies();
866 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
868 void MEDFileMesh::checkOrphanFamilyZero() const
870 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
872 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
874 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
875 throw INTERP_KERNEL::Exception(oss.str().c_str());
881 * Renames a group in \a this mesh.
882 * \param [in] oldName - a current name of the group to rename.
883 * \param [in] newName - a new group name.
884 * \throw If no group named \a oldName exists in \a this mesh.
885 * \throw If a group named \a newName already exists.
887 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
889 std::string oname(oldName);
890 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
891 std::vector<std::string> grps=getGroupsNames();
892 if(it==_groups.end())
894 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
895 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
896 throw INTERP_KERNEL::Exception(oss.str().c_str());
898 std::string nname(newName);
899 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
900 if(it2!=_groups.end())
902 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
903 throw INTERP_KERNEL::Exception(oss.str().c_str());
905 std::vector<std::string> cpy=(*it).second;
907 _groups[newName]=cpy;
911 * Changes an id of a family in \a this mesh.
912 * This method calls changeFamilyIdArr().
913 * \param [in] oldId - a current id of the family.
914 * \param [in] newId - a new family id.
916 void MEDFileMesh::changeFamilyId(int oldId, int newId)
918 changeFamilyIdArr(oldId,newId);
919 std::map<std::string,int> fam2;
920 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
922 if((*it).second==oldId)
923 fam2[(*it).first]=newId;
925 fam2[(*it).first]=(*it).second;
931 * Renames a family in \a this mesh.
932 * \param [in] oldName - a current name of the family to rename.
933 * \param [in] newName - a new family name.
934 * \throw If no family named \a oldName exists in \a this mesh.
935 * \throw If a family named \a newName already exists.
937 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
939 std::string oname(oldName);
940 std::map<std::string, int >::iterator it=_families.find(oname);
941 std::vector<std::string> fams=getFamiliesNames();
942 if(it==_families.end())
944 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
945 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
946 throw INTERP_KERNEL::Exception(oss.str().c_str());
948 std::string nname(newName);
949 std::map<std::string, int >::iterator it2=_families.find(nname);
950 if(it2!=_families.end())
952 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
953 throw INTERP_KERNEL::Exception(oss.str().c_str());
955 int cpy=(*it).second;
957 _families[newName]=cpy;
958 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
960 std::vector<std::string>& v=(*it3).second;
961 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
968 * Checks if \a this and another mesh contains the same families.
969 * \param [in] other - the mesh to compare with \a this one.
970 * \param [in,out] what - an unused parameter.
971 * \return bool - \c true if number of families and their ids are the same in the two
972 * meshes. Families with the id == \c 0 are not considered.
974 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
976 if(_families==other->_families)
978 std::map<std::string,int> fam0;
979 std::map<std::string,int> fam1;
980 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
982 fam0[(*it).first]=(*it).second;
983 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
985 fam1[(*it).first]=(*it).second;
990 * Checks if \a this and another mesh contains the same groups.
991 * \param [in] other - the mesh to compare with \a this one.
992 * \param [in,out] what - a string describing a difference of groups of the two meshes
993 * in case if this method returns \c false.
994 * \return bool - \c true if number of groups and families constituting them are the
995 * same in the two meshes.
997 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
999 if(_groups==other->_groups)
1002 std::size_t sz=_groups.size();
1003 if(sz!=other->_groups.size())
1005 what="Groups differ because not same number !\n";
1010 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
1011 for(std::size_t i=0;i<sz && ret;i++,it1++)
1013 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
1014 if(it2!=other->_groups.end())
1016 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
1017 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1023 what="A group in first mesh exists not in other !\n";
1029 std::ostringstream oss; oss << "Groups description differs :\n";
1030 oss << "First group description :\n";
1031 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1033 oss << " Group \"" << (*it).first << "\" on following families :\n";
1034 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1035 oss << " \"" << *it2 << "\n";
1037 oss << "Second group description :\n";
1038 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1040 oss << " Group \"" << (*it).first << "\" on following families :\n";
1041 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1042 oss << " \"" << *it2 << "\n";
1050 * Checks if a group with a given name exists in \a this mesh.
1051 * \param [in] groupName - the group name.
1052 * \return bool - \c true the group \a groupName exists in \a this mesh.
1054 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1056 std::string grpName(groupName);
1057 return _groups.find(grpName)!=_groups.end();
1061 * Checks if a family with a given id exists in \a this mesh.
1062 * \param [in] famId - the family id.
1063 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1065 bool MEDFileMesh::existsFamily(int famId) const
1067 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1068 if((*it2).second==famId)
1074 * Checks if a family with a given name exists in \a this mesh.
1075 * \param [in] familyName - the family name.
1076 * \return bool - \c true the family \a familyName exists in \a this mesh.
1078 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1080 std::string fname(familyName);
1081 return _families.find(fname)!=_families.end();
1085 * Sets an id of a family.
1086 * \param [in] familyName - the family name.
1087 * \param [in] id - a new id of the family.
1089 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1091 std::string fname(familyName);
1092 _families[fname]=id;
1095 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1097 std::string fname(familyName);
1098 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1099 if((*it).second==id)
1101 if((*it).first!=familyName)
1103 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1104 throw INTERP_KERNEL::Exception(oss.str().c_str());
1107 _families[fname]=id;
1111 * Adds a family to \a this mesh.
1112 * \param [in] familyName - a name of the family.
1113 * \param [in] famId - an id of the family.
1114 * \throw If a family with the same name or id already exists in \a this mesh.
1116 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1118 std::string fname(familyName);
1119 std::map<std::string,int>::const_iterator it=_families.find(fname);
1120 if(it==_families.end())
1122 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1123 if((*it2).second==famId)
1125 std::ostringstream oss;
1126 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1127 throw INTERP_KERNEL::Exception(oss.str().c_str());
1129 _families[fname]=famId;
1133 if((*it).second!=famId)
1135 std::ostringstream oss;
1136 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1137 throw INTERP_KERNEL::Exception(oss.str().c_str());
1143 * Creates a group including all mesh entities of given dimension.
1144 * \warning This method does \b not guarantee that the created group includes mesh
1145 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1146 * present in family fields of different dimensions. To assure this, call
1147 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1148 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1150 * \param [in] groupName - a name of the new group.
1151 * \throw If a group named \a groupName already exists.
1152 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1153 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1155 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1157 std::string grpName(groupName);
1158 std::vector<int> levs=getNonEmptyLevelsExt();
1159 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1161 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1162 oss << "Available relative ext levels are : ";
1163 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1164 throw INTERP_KERNEL::Exception(oss.str().c_str());
1166 if(existsGroup(groupName))
1168 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1169 oss << "Already existing groups are : ";
1170 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1171 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1172 throw INTERP_KERNEL::Exception(oss.str().c_str());
1174 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1176 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1177 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1178 std::vector<std::string> familiesOnWholeGroup;
1179 for(const int *it=famIds->begin();it!=famIds->end();it++)
1182 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1184 _groups[grpName]=familiesOnWholeGroup;
1188 * Ensures that given family ids do not present in family fields of dimensions different
1189 * than given ones. If a family id is present in the family fields of dimensions different
1190 * than the given ones, a new family is created and the whole data is updated accordingly.
1191 * \param [in] famIds - a sequence of family ids to check.
1192 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1193 * famIds should exclusively belong.
1194 * \return bool - \c true if no modification is done in \a this mesh by this method.
1196 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1198 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1199 std::vector<int> levs=getNonEmptyLevelsExt();
1200 std::set<int> levs2(levs.begin(),levs.end());
1201 std::vector<int> levsToTest;
1202 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1203 std::set<int> famIds2(famIds.begin(),famIds.end());
1206 if(!_families.empty())
1207 maxFamId=getMaxFamilyId()+1;
1208 std::vector<std::string> allFams=getFamiliesNames();
1209 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1211 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1214 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1215 std::vector<int> tmp;
1216 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1217 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1220 std::string famName=getFamilyNameGivenId(*it2);
1221 std::ostringstream oss; oss << "Family_" << maxFamId;
1222 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1223 addFamilyOnAllGroupsHaving(famName,zeName);
1224 _families[zeName]=maxFamId;
1225 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1234 * Adds a family to a given group in \a this mesh. If the group with a given name does
1235 * not exist, it is created.
1236 * \param [in] grpName - the name of the group to add the family in.
1237 * \param [in] famName - the name of the family to add to the group named \a grpName.
1238 * \throw If \a grpName or \a famName is an empty string.
1239 * \throw If no family named \a famName is present in \a this mesh.
1241 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1243 std::string grpn(grpName);
1244 std::string famn(famName);
1245 if(grpn.empty() || famn.empty())
1246 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1247 std::vector<std::string> fams=getFamiliesNames();
1248 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1250 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1251 oss << "Create this family or choose an existing one ! Existing fams are : ";
1252 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1253 throw INTERP_KERNEL::Exception(oss.str().c_str());
1255 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1256 if(it==_groups.end())
1258 _groups[grpn].push_back(famn);
1262 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1263 if(it2==(*it).second.end())
1264 (*it).second.push_back(famn);
1269 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1270 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1271 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1273 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1275 std::string famNameCpp(famName);
1276 std::string otherCpp(otherFamName);
1277 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1279 std::vector<std::string>& v=(*it).second;
1280 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1282 v.push_back(otherCpp);
1287 void MEDFileMesh::checkNoGroupClash(const DataArrayInt *famArr, const std::string& grpName) const
1289 std::vector<std::string> grpsNames(getGroupsNames());
1290 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
1292 std::vector<int> famIds(getFamiliesIdsOnGroup(grpName));
1293 if(famArr->presenceOfValue(famIds))
1295 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
1296 throw INTERP_KERNEL::Exception(oss.str().c_str());
1301 * \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).
1302 * \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)
1304 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1307 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1308 std::string grpName(ids->getName());
1310 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1311 ids->checkStrictlyMonotonic(true);
1312 checkNoGroupClash(famArr,grpName);
1313 MCAuto<DataArrayInt> famArrTmp; famArrTmp.takeRef(famArr);
1314 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1315 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1316 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1317 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1318 std::vector<int> familyIds;
1319 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1320 int maxVal=getTheMaxAbsFamilyId()+1;
1321 std::map<std::string,int> families(_families);
1322 std::map<std::string, std::vector<std::string> > groups(_groups);
1323 std::vector<std::string> fams;
1324 bool created(false);
1325 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1327 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1328 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1329 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1330 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1333 bool isFamPresent=false;
1334 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1335 isFamPresent=(*itl)->presenceOfValue(*famId);
1336 if(!isFamPresent && *famId!=0)
1337 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1340 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1341 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1342 fams.push_back(locFamName);
1343 if(existsFamily(*famId))
1345 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1346 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1349 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1353 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1354 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1355 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1356 if(existsFamily(*famId))
1358 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1359 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1364 for(std::size_t i=0;i<familyIds.size();i++)
1366 DataArrayInt *da=idsPerfamiliyIds[i];
1367 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1370 std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
1371 if(itt!=groups.end())
1373 std::vector<std::string>& famsOnGrp((*itt).second);
1374 famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
1377 groups[grpName]=fams;
1381 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1383 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1386 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1388 std::string fam(familyNameToChange);
1389 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1391 std::vector<std::string>& fams((*it).second);
1392 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1396 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1402 * Returns a name of the family having a given id or, if no such a family exists, creates
1403 * a new uniquely named family and returns its name.
1404 * \param [in] id - the id of the family whose name is required.
1405 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1406 * \return std::string - the name of the existing or the created family.
1407 * \throw If it is not possible to create a unique family name.
1409 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1411 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1415 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1416 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1417 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1418 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1420 * This method will throws an exception if it is not possible to create a unique family name.
1422 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1424 std::vector<std::string> famAlreadyExisting(families.size());
1426 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1428 if((*it).second!=id)
1430 famAlreadyExisting[ii]=(*it).first;
1439 std::ostringstream oss; oss << "Family_" << id;
1440 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1446 * Sets names and ids of all families in \a this mesh.
1447 * \param [in] info - a map of a family name to a family id.
1449 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1455 * Sets names of all groups and families constituting them in \a this mesh.
1456 * \param [in] info - a map of a group name to a vector of names of families
1457 * constituting the group.
1459 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1465 * Returns an id of the family having a given name.
1466 * \param [in] name - the name of the family of interest.
1467 * \return int - the id of the family of interest.
1468 * \throw If no family with such a \a name exists.
1470 int MEDFileMesh::getFamilyId(const std::string& name) const
1472 std::map<std::string, int>::const_iterator it=_families.find(name);
1473 if(it==_families.end())
1475 std::vector<std::string> fams(getFamiliesNames());
1476 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1477 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1478 throw INTERP_KERNEL::Exception(oss.str().c_str());
1480 return (*it).second;
1484 * Returns ids of the families having given names.
1485 * \param [in] fams - a sequence of the names of families of interest.
1486 * \return std::vector<int> - a sequence of the ids of families of interest.
1487 * \throw If \a fams contains a name of an inexistent family.
1489 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1491 std::vector<int> ret(fams.size());
1493 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1495 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1496 if(it2==_families.end())
1498 std::vector<std::string> fams2=getFamiliesNames();
1499 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1500 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1501 throw INTERP_KERNEL::Exception(oss.str().c_str());
1503 ret[i]=(*it2).second;
1509 * Returns a maximal abs(id) of families in \a this mesh.
1510 * \return int - the maximal norm of family id.
1511 * \throw If there are no families in \a this mesh.
1513 int MEDFileMesh::getMaxAbsFamilyId() const
1515 if(_families.empty())
1516 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1517 int ret=-std::numeric_limits<int>::max();
1518 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1520 ret=std::max(std::abs((*it).second),ret);
1526 * Returns a maximal id of families in \a this mesh.
1527 * \return int - the maximal family id.
1528 * \throw If there are no families in \a this mesh.
1530 int MEDFileMesh::getMaxFamilyId() const
1532 if(_families.empty())
1533 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1534 int ret=-std::numeric_limits<int>::max();
1535 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1537 ret=std::max((*it).second,ret);
1543 * Returns a minimal id of families in \a this mesh.
1544 * \return int - the minimal family id.
1545 * \throw If there are no families in \a this mesh.
1547 int MEDFileMesh::getMinFamilyId() const
1549 if(_families.empty())
1550 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1551 int ret=std::numeric_limits<int>::max();
1552 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1554 ret=std::min((*it).second,ret);
1560 * Returns a maximal id of families in \a this mesh. Not only named families are
1561 * considered but all family fields as well.
1562 * \return int - the maximal family id.
1564 int MEDFileMesh::getTheMaxAbsFamilyId() const
1566 int m1=-std::numeric_limits<int>::max();
1567 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1568 m1=std::max(std::abs((*it).second),m1);
1569 int m2=getMaxAbsFamilyIdInArrays();
1570 return std::max(m1,m2);
1574 * Returns a maximal id of families in \a this mesh. Not only named families are
1575 * considered but all family fields as well.
1576 * \return int - the maximal family id.
1578 int MEDFileMesh::getTheMaxFamilyId() const
1580 int m1=-std::numeric_limits<int>::max();
1581 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1582 m1=std::max((*it).second,m1);
1583 int m2=getMaxFamilyIdInArrays();
1584 return std::max(m1,m2);
1588 * Returns a minimal id of families in \a this mesh. Not only named families are
1589 * considered but all family fields as well.
1590 * \return int - the minimal family id.
1592 int MEDFileMesh::getTheMinFamilyId() const
1594 int m1=std::numeric_limits<int>::max();
1595 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1596 m1=std::min((*it).second,m1);
1597 int m2=getMinFamilyIdInArrays();
1598 return std::min(m1,m2);
1602 * This method only considers the maps. The contain of family array is ignored here.
1604 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1606 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1608 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1610 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1611 v.insert((*it).second);
1612 ret->alloc((int)v.size(),1);
1613 std::copy(v.begin(),v.end(),ret->getPointer());
1618 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1620 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1622 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1624 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1625 MCAuto<DataArrayInt> ret;
1626 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1628 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1629 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1630 if((DataArrayInt *) ret)
1631 ret=dv->buildUnion(ret);
1639 * true is returned if no modification has been needed. false if family
1640 * renumbering has been needed.
1642 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1644 std::vector<int> levs=getNonEmptyLevelsExt();
1645 std::set<int> allFamIds;
1646 int maxId=getMaxFamilyId()+1;
1647 std::map<int,std::vector<int> > famIdsToRenum;
1648 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1650 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1653 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1655 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1657 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1659 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1662 if(famIdsToRenum.empty())
1664 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1665 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1667 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1668 int *famIdsToChange=fam->getPointer();
1669 std::map<int,int> ren;
1670 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1672 if(allIds->presenceOfValue(*it3))
1674 std::string famName=getFamilyNameGivenId(*it3);
1675 std::vector<std::string> grps=getGroupsOnFamily(famName);
1678 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1679 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1680 addFamilyOnGrp((*it4),newFam);
1683 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1684 for(const int *id=ids->begin();id!=ids->end();id++)
1685 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1691 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1692 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1693 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1694 * This method will throw an exception if a same family id is detected in different level.
1695 * \warning This policy is the opposite of those in MED file documentation ...
1697 void MEDFileMesh::normalizeFamIdsTrio()
1699 ensureDifferentFamIdsPerLevel();
1700 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1701 std::vector<int> levs=getNonEmptyLevelsExt();
1702 std::set<int> levsS(levs.begin(),levs.end());
1703 std::set<std::string> famsFetched;
1704 std::map<std::string,int> families;
1705 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1708 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1712 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1713 std::map<int,int> ren;
1714 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1716 int nbOfTuples=fam->getNumberOfTuples();
1717 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1718 for(int *w=start;w!=start+nbOfTuples;w++)
1720 for(const int *it=tmp->begin();it!=tmp->end();it++)
1722 if(allIds->presenceOfValue(*it))
1724 std::string famName=getFamilyNameGivenId(*it);
1725 families[famName]=ren[*it];
1726 famsFetched.insert(famName);
1731 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1734 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1738 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1739 std::map<int,int> ren;
1740 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1742 int nbOfTuples=fam->getNumberOfTuples();
1743 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1744 for(int *w=start;w!=start+nbOfTuples;w++)
1746 for(const int *it=tmp->begin();it!=tmp->end();it++)
1748 if(allIds->presenceOfValue(*it))
1750 std::string famName=getFamilyNameGivenId(*it);
1751 families[famName]=ren[*it];
1752 famsFetched.insert(famName);
1757 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1759 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1762 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1763 fam->fillWithZero();
1764 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1765 if(allIds->presenceOfValue(*it3))
1767 std::string famName=getFamilyNameGivenId(*it3);
1768 families[famName]=0;
1769 famsFetched.insert(famName);
1774 std::vector<std::string> allFams=getFamiliesNames();
1775 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1776 std::set<std::string> unFetchedIds;
1777 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1778 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1779 families[*it4]=_families[*it4];
1784 * This method normalizes fam id with the following policy.
1785 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1786 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1787 * This method will throw an exception if a same family id is detected in different level.
1789 void MEDFileMesh::normalizeFamIdsMEDFile()
1791 ensureDifferentFamIdsPerLevel();
1792 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1793 std::vector<int> levs=getNonEmptyLevelsExt();
1794 std::set<int> levsS(levs.begin(),levs.end());
1795 std::set<std::string> famsFetched;
1796 std::map<std::string,int> families;
1798 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1801 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1804 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1805 std::map<int,int> ren;
1806 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1808 int nbOfTuples=fam->getNumberOfTuples();
1809 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1810 for(int *w=start;w!=start+nbOfTuples;w++)
1812 for(const int *it=tmp->begin();it!=tmp->end();it++)
1814 if(allIds->presenceOfValue(*it))
1816 std::string famName=getFamilyNameGivenId(*it);
1817 families[famName]=ren[*it];
1818 famsFetched.insert(famName);
1824 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1826 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1829 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1830 std::map<int,int> ren;
1831 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1833 int nbOfTuples=fam->getNumberOfTuples();
1834 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1835 for(int *w=start;w!=start+nbOfTuples;w++)
1837 for(const int *it=tmp->begin();it!=tmp->end();it++)
1839 if(allIds->presenceOfValue(*it))
1841 std::string famName=getFamilyNameGivenId(*it);
1842 families[famName]=ren[*it];
1843 famsFetched.insert(famName);
1849 std::vector<std::string> allFams=getFamiliesNames();
1850 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1851 std::set<std::string> unFetchedIds;
1852 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1853 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1854 families[*it4]=_families[*it4];
1859 * Returns a name of the family by its id. If there are several families having the given
1860 * id, the name first in lexical order is returned.
1861 * \param [in] id - the id of the family whose name is required.
1862 * \return std::string - the name of the found family.
1863 * \throw If no family with the given \a id exists.
1865 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1867 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1868 if((*it).second==id)
1870 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1871 throw INTERP_KERNEL::Exception(oss.str().c_str());
1875 * Returns a string describing \a this mesh. This description includes the mesh name and
1876 * the mesh description string.
1877 * \return std::string - the mesh information string.
1879 std::string MEDFileMesh::simpleRepr() const
1881 std::ostringstream oss;
1882 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1883 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1884 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1889 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1890 * an empty one is created.
1892 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1894 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1897 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1898 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1899 arr->fillWithZero();
1900 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1901 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1905 * Returns ids of mesh entities contained in a given group of a given dimension.
1906 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1908 * \param [in] grp - the name of the group of interest.
1909 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1910 * returned instead of ids.
1911 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1912 * numbers, if available and required, of mesh entities of the group. The caller
1913 * is to delete this array using decrRef() as it is no more needed.
1914 * \throw If the name of a nonexistent group is specified.
1915 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1917 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1919 std::vector<std::string> tmp(1);
1921 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1927 * Returns ids of mesh entities contained in given groups of a given dimension.
1928 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1930 * \param [in] grps - the names of the groups of interest.
1931 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1932 * returned instead of ids.
1933 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1934 * numbers, if available and required, of mesh entities of the groups. The caller
1935 * is to delete this array using decrRef() as it is no more needed.
1936 * \throw If the name of a nonexistent group is present in \a grps.
1937 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1939 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1941 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1942 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1946 * Returns ids of mesh entities contained in a given family of a given dimension.
1947 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1949 * \param [in] fam - the name of the family of interest.
1950 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1951 * returned instead of ids.
1952 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1953 * numbers, if available and required, of mesh entities of the family. The caller
1954 * is to delete this array using decrRef() as it is no more needed.
1955 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1957 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1959 std::vector<std::string> tmp(1);
1961 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1967 * Returns ids of nodes contained in a given group.
1968 * \param [in] grp - the name of the group of interest.
1969 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1970 * returned instead of ids.
1971 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1972 * numbers, if available and required, of nodes of the group. The caller
1973 * is to delete this array using decrRef() as it is no more needed.
1974 * \throw If the name of a nonexistent group is specified.
1975 * \throw If the family field is missing for nodes.
1977 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1979 std::vector<std::string> tmp(1);
1981 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1987 * Returns ids of nodes contained in given groups.
1988 * \param [in] grps - the names of the groups of interest.
1989 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1990 * returned instead of ids.
1991 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1992 * numbers, if available and required, of nodes of the groups. The caller
1993 * is to delete this array using decrRef() as it is no more needed.
1994 * \throw If the name of a nonexistent group is present in \a grps.
1995 * \throw If the family field is missing for nodes.
1997 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1999 return getGroupsArr(1,grps,renum);
2003 * Returns ids of nodes contained in a given group.
2004 * \param [in] grp - the name of the group of interest.
2005 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2006 * returned instead of ids.
2007 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2008 * numbers, if available and required, of nodes of the group. The caller
2009 * is to delete this array using decrRef() as it is no more needed.
2010 * \throw If the name of a nonexistent group is specified.
2011 * \throw If the family field is missing for nodes.
2013 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
2015 std::vector<std::string> tmp(1);
2017 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
2023 * Returns ids of nodes contained in given families.
2024 * \param [in] fams - the names of the families of interest.
2025 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2026 * returned instead of ids.
2027 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2028 * numbers, if available and required, of nodes of the families. The caller
2029 * is to delete this array using decrRef() as it is no more needed.
2030 * \throw If the family field is missing for nodes.
2032 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2034 return getFamiliesArr(1,fams,renum);
2038 * Adds groups of given dimension and creates corresponding families and family fields
2039 * given ids of mesh entities of each group.
2040 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2041 * \param [in] grps - a sequence of arrays of ids each describing a group.
2042 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2044 * \throw If names of some groups in \a grps are equal.
2045 * \throw If \a grps includes a group with an empty name.
2046 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2047 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2049 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2053 std::set<std::string> grpsName;
2054 std::vector<std::string> grpsName2(grps.size());
2057 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2059 grpsName.insert((*it)->getName());
2060 grpsName2[i]=(*it)->getName();
2062 if(grpsName.size()!=grps.size())
2063 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2064 if(grpsName.find(std::string(""))!=grpsName.end())
2065 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2066 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2067 MCAuto<DataArrayInt> fam;
2068 std::vector< std::vector<int> > fidsOfGroups;
2071 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2075 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2076 for(unsigned int ii=0;ii<grps.size();ii++)
2078 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2079 grps2[ii]->setName(grps[ii]->getName());
2081 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2082 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2085 if(!_families.empty())
2086 offset=getMaxAbsFamilyId()+1;
2087 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2088 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2089 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2090 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2094 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2095 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2096 * For the moment, the two last input parameters are not taken into account.
2098 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2100 std::map<int,std::string> famInv;
2101 for(const int *it=famIds->begin();it!=famIds->end();it++)
2103 std::ostringstream oss;
2104 oss << "Family_" << (*it);
2105 _families[oss.str()]=(*it);
2106 famInv[*it]=oss.str();
2109 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2111 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2113 _groups[grpNames[i]].push_back(famInv[*it2]);
2118 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2120 std::vector<int> levs(getNonEmptyLevels());
2121 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2122 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2124 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2125 ret.insert(ret.end(),elts.begin(),elts.end());
2131 * \sa getAllDistributionOfTypes
2133 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2135 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2136 return mLev->getDistributionOfTypes();
2139 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2141 loadLL(fid,mName,dt,it,mrs);
2142 loadJointsFromFile(fid);
2143 loadEquivalences(fid);
2146 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2148 famArr->applyLin(offset>0?1:-1,offset,0);
2149 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2152 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2153 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2158 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2159 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2160 * If this method fails to find such a name it will throw an exception.
2162 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2165 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2168 std::size_t len=nameTry.length();
2169 for(std::size_t ii=1;ii<len;ii++)
2171 std::string tmp=nameTry.substr(ii,len-ii);
2172 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2178 for(std::size_t i=1;i<30;i++)
2180 std::string tmp1(nameTry.at(0),i);
2182 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2188 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2190 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2192 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2195 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2197 std::size_t nbOfChunks=code.size()/3;
2198 if(code.size()%3!=0)
2199 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2201 for(std::size_t i=0;i<nbOfChunks;i++)
2210 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2211 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2212 * If _name is not empty and that 'm' has the same name nothing is done.
2213 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2215 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2218 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2223 std::string name(m->getName());
2228 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2229 oss << name << "' ! Names must match !";
2230 throw INTERP_KERNEL::Exception(oss.str().c_str());
2234 if(_desc_name.empty())
2235 _desc_name=m->getDescription();
2238 std::string name(m->getDescription());
2241 if(_desc_name!=name)
2243 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2244 oss << name << "' ! Names must match !";
2245 throw INTERP_KERNEL::Exception(oss.str().c_str());
2251 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2253 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2254 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2256 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2257 oss << " - Groups lying on this family : ";
2258 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2259 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2260 oss << std::endl << std::endl;
2265 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2266 * file. The mesh to load is specified by its name and numbers of a time step and an
2268 * \param [in] fileName - the name of MED file to read.
2269 * \param [in] mName - the name of the mesh to read.
2270 * \param [in] dt - the number of a time step.
2271 * \param [in] it - the number of an iteration.
2272 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2273 * mesh using decrRef() as it is no more needed.
2274 * \throw If the file is not readable.
2275 * \throw If there is no mesh with given attributes in the file.
2276 * \throw If the mesh in the file is not an unstructured one.
2278 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2280 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2281 return New(fid,mName,dt,it,mrs);
2284 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2286 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2290 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2291 * file. The first mesh in the file is loaded.
2292 * \param [in] fileName - the name of MED file to read.
2293 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2294 * mesh using decrRef() as it is no more needed.
2295 * \throw If the file is not readable.
2296 * \throw If there is no meshes in the file.
2297 * \throw If the mesh in the file is not an unstructured one.
2299 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2301 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2302 return New(fid,mrs);
2306 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2308 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2311 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2312 throw INTERP_KERNEL::Exception(oss.str().c_str());
2315 MEDCoupling::MEDCouplingMeshType meshType;
2317 MEDCoupling::MEDCouplingAxisType dummy3;
2318 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2319 return T::New(fid,ms.front(),dt,it,mrs);
2322 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2324 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2328 * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2329 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2331 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2334 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2335 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2336 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2337 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2339 m2D->setCoords(m3D->getCoords());
2340 ret->setMeshAtLevel(0,m3D);
2341 ret->setMeshAtLevel(-1,m2D);
2342 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2347 * Returns an empty instance of MEDFileUMesh.
2348 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2349 * mesh using decrRef() as it is no more needed.
2351 MEDFileUMesh *MEDFileUMesh::New()
2353 return new MEDFileUMesh;
2357 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2358 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2359 * \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.
2360 * 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
2361 * at most the memory consumtion.
2363 * \param [in] fileName - the name of the file.
2364 * \param [in] mName - the name of the mesh to be read.
2365 * \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.
2366 * \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.
2367 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2368 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2369 * \param [in] mrs - the request for what to be loaded.
2370 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2372 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)
2374 MEDFileUtilities::CheckFileForRead(fileName);
2375 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2376 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2380 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2381 * This method is \b NOT wrapped into python.
2383 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)
2385 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2386 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2390 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2392 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2393 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2397 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2399 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2400 ret.push_back((const DataArrayDouble*)_coords);
2401 ret.push_back((const DataArrayInt *)_fam_coords);
2402 ret.push_back((const DataArrayInt *)_num_coords);
2403 ret.push_back((const DataArrayInt *)_global_num_coords);
2404 ret.push_back((const DataArrayInt *)_rev_num_coords);
2405 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2406 ret.push_back((const PartDefinition *)_part_coords);
2407 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2408 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2409 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2410 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2414 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2416 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2420 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2422 return new MEDFileUMesh;
2425 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2427 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2428 ret->deepCpyEquivalences(*this);
2429 if(_coords.isNotNull())
2430 ret->_coords=_coords->deepCopy();
2431 if(_fam_coords.isNotNull())
2432 ret->_fam_coords=_fam_coords->deepCopy();
2433 if(_num_coords.isNotNull())
2434 ret->_num_coords=_num_coords->deepCopy();
2435 if(_global_num_coords.isNotNull())
2436 ret->_global_num_coords=_global_num_coords->deepCopy();
2437 if(_rev_num_coords.isNotNull())
2438 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2439 if(_name_coords.isNotNull())
2440 ret->_name_coords=_name_coords->deepCopy();
2442 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2444 if((const MEDFileUMeshSplitL1 *)(*it))
2445 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2447 if((const PartDefinition*)_part_coords)
2448 ret->_part_coords=_part_coords->deepCopy();
2453 * Checks if \a this and another mesh are equal.
2454 * \param [in] other - the mesh to compare with.
2455 * \param [in] eps - a precision used to compare real values.
2456 * \param [in,out] what - the string returning description of unequal data.
2457 * \return bool - \c true if the meshes are equal, \c false, else.
2459 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2461 if(!MEDFileMesh::isEqual(other,eps,what))
2463 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2466 what="Mesh types differ ! This is unstructured and other is NOT !";
2469 clearNonDiscrAttributes();
2470 otherC->clearNonDiscrAttributes();
2471 const DataArrayDouble *coo1=_coords;
2472 const DataArrayDouble *coo2=otherC->_coords;
2473 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2475 what="Mismatch of coordinates ! One is defined and not other !";
2480 bool ret=coo1->isEqual(*coo2,eps);
2483 what="Coords differ !";
2488 const DataArrayInt *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2489 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2491 what="Mismatch of families arr on nodes ! One is defined and not other !";
2496 bool ret=famc1->isEqual(*famc2);
2499 what="Families arr on node differ !";
2505 const DataArrayInt *numc1(_num_coords),*numc2(otherC->_num_coords);
2506 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2508 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2513 bool ret=numc1->isEqual(*numc2);
2516 what="Numbering arr on node differ !";
2522 const DataArrayInt *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2523 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2525 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2530 bool ret=gnumc1->isEqual(*gnumc2);
2533 what="Global numbering arr on node differ !";
2539 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2540 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2542 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2547 bool ret=namec1->isEqual(*namec2);
2550 what="Names arr on node differ !";
2555 if(_ms.size()!=otherC->_ms.size())
2557 what="Number of levels differs !";
2560 std::size_t sz=_ms.size();
2561 for(std::size_t i=0;i<sz;i++)
2563 const MEDFileUMeshSplitL1 *s1=_ms[i];
2564 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2565 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2567 what="Mismatch of presence of sub levels !";
2572 bool ret=s1->isEqual(s2,eps,what);
2577 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2580 if((!pd0 && pd1) || (pd0 && !pd1))
2582 what=std::string("node part def is defined only for one among this or other !");
2585 return pd0->isEqual(pd1,what);
2589 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2590 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2591 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2592 * \throw if internal family array is inconsistent
2593 * \sa checkSMESHConsistency()
2595 void MEDFileUMesh::checkConsistency() const
2597 if(!_coords || !_coords->isAllocated())
2600 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2602 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2603 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2604 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2608 int nbCoo = _coords->getNumberOfTuples();
2609 if (_fam_coords.isNotNull())
2610 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2611 if (_num_coords.isNotNull())
2613 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2615 int maxValue=_num_coords->getMaxValue(pos);
2616 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2617 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2619 if (_global_num_coords.isNotNull())
2621 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2623 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2624 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2625 if (_num_coords && !_num_coords->hasUniqueValues())
2626 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2628 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2629 // Now sub part check:
2630 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2631 it != _ms.end(); it++)
2632 (*it)->checkConsistency();
2637 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2638 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2639 * entities as it likes), or non overlapping between all sub-levels.
2640 * \throw if the condition above is not respected
2642 void MEDFileUMesh::checkSMESHConsistency() const
2645 // For all sub-levels, numbering is either always null or with void intersection:
2648 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2649 std::vector< const DataArrayInt * > v;
2650 bool voidOrNot = ((*it)->_num == 0);
2651 for (it++; it != _ms.end(); it++)
2652 if( ((*it)->_num == 0) != voidOrNot )
2653 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2654 else if (!voidOrNot)
2655 v.push_back((*it)->_num);
2658 // don't forget the 1st one:
2659 v.push_back(_ms[0]->_num);
2660 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2661 if (inter->getNumberOfTuples())
2662 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2668 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2669 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2671 void MEDFileUMesh::clearNodeAndCellNumbers()
2673 _num_coords.nullify();
2674 _rev_num_coords.nullify();
2675 _global_num_coords.nullify();
2676 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2678 (*it)->_num.nullify();
2679 (*it)->_rev_num.nullify();
2680 (*it)->_global_num.nullify();
2685 * Clears redundant attributes of incorporated data arrays.
2687 void MEDFileUMesh::clearNonDiscrAttributes() const
2689 MEDFileMesh::clearNonDiscrAttributes();
2690 if(_coords.isNotNull())
2691 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2692 if(_fam_coords.isNotNull())
2693 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2694 if(_num_coords.isNotNull())
2695 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2696 if(_name_coords.isNotNull())
2697 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2698 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2700 if((*it).isNotNull())
2701 (*it)->clearNonDiscrAttributes();
2705 void MEDFileUMesh::setName(const std::string& name)
2707 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2708 if((*it).isNotNull())
2709 (*it)->setName(name);
2710 MEDFileMesh::setName(name);
2713 MEDFileUMesh::MEDFileUMesh()
2717 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2720 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2722 catch(INTERP_KERNEL::Exception& e)
2728 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2729 * See MEDFileUMesh::LoadPartOf for detailed description.
2733 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)
2735 MEDFileUMeshL2 loaderl2;
2736 MEDCoupling::MEDCouplingMeshType meshType;
2739 MEDCoupling::MEDCouplingAxisType dummy3;
2740 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2741 if(meshType!=UNSTRUCTURED)
2743 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2744 throw INTERP_KERNEL::Exception(oss.str().c_str());
2746 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2747 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2751 * \brief Write joints in a file
2753 void MEDFileMesh::writeJoints(med_idt fid) const
2755 if ( _joints.isNotNull() )
2756 _joints->writeLL(fid);
2760 * \brief Load joints in a file or use provided ones
2762 //================================================================================
2764 * \brief Load joints in a file or use provided ones
2765 * \param [in] fid - MED file descriptor
2766 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2767 * Usually this joints are those just read by another iteration
2768 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2770 //================================================================================
2772 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2774 if ( toUseInstedOfReading )
2775 setJoints( toUseInstedOfReading );
2777 _joints = MEDFileJoints::New( fid, _name );
2780 void MEDFileMesh::loadEquivalences(med_idt fid)
2782 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2784 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2787 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2789 const MEDFileEquivalences *equiv(other._equiv);
2791 _equiv=equiv->deepCopy(this);
2794 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2796 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2797 if(!thisEq && !otherEq)
2799 if(thisEq && otherEq)
2800 return thisEq->isEqual(otherEq,what);
2803 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2808 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2810 const MEDFileEquivalences *equiv(_equiv);
2813 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2814 _equiv->getRepr(oss);
2817 void MEDFileMesh::checkCartesian() const
2819 if(getAxisType()!=AX_CART)
2821 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()) << ").";
2822 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2823 oss << " - call setAxisType(AX_CART)" << std::endl;
2824 oss << " - call cartesianize()";
2825 throw INTERP_KERNEL::Exception(oss.str().c_str());
2830 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2832 int MEDFileMesh::getNumberOfJoints() const
2834 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2838 * \brief Return joints with all adjacent mesh domains
2840 MEDFileJoints * MEDFileMesh::getJoints() const
2842 return const_cast<MEDFileJoints*>(& (*_joints));
2845 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2847 if ( joints != _joints )
2856 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2858 * \sa loadPartUMeshFromFile
2860 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2862 MEDFileUMeshL2 loaderl2;
2863 MEDCoupling::MEDCouplingMeshType meshType;
2866 MEDCoupling::MEDCouplingAxisType axType;
2867 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2868 setAxisType(axType);
2869 if(meshType!=UNSTRUCTURED)
2871 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2872 throw INTERP_KERNEL::Exception(oss.str().c_str());
2874 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2875 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2876 // Structure element part...
2879 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2880 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2884 _elt_str.resize(nModels);
2885 for(int i=0;i<nModels;i++)
2886 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2889 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2891 int lev=loaderl2.getNumberOfLevels();
2893 for(int i=0;i<lev;i++)
2895 if(!loaderl2.emptyLev(i))
2896 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2900 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2902 setName(loaderl2.getName());
2903 setDescription(loaderl2.getDescription());
2904 setUnivName(loaderl2.getUnivName());
2905 setIteration(loaderl2.getIteration());
2906 setOrder(loaderl2.getOrder());
2907 setTimeValue(loaderl2.getTime());
2908 setTimeUnit(loaderl2.getTimeUnit());
2909 _coords=loaderl2.getCoords();
2910 if(!mrs || mrs->isNodeFamilyFieldReading())
2911 _fam_coords=loaderl2.getCoordsFamily();
2912 if(!mrs || mrs->isNodeNumFieldReading())
2913 _num_coords=loaderl2.getCoordsNum();
2914 if(!mrs || mrs->isNodeNameFieldReading())
2915 _name_coords=loaderl2.getCoordsName();
2916 if(!mrs || mrs->isGlobalNodeNumFieldReading())
2917 _global_num_coords=loaderl2.getCoordsGlobalNum();
2918 _part_coords=loaderl2.getPartDefOfCoo();
2922 MEDFileUMesh::~MEDFileUMesh()
2926 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2928 const DataArrayDouble *coo=_coords;
2929 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2930 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2931 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2932 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2933 int spaceDim=coo?coo->getNumberOfComponents():0;
2936 mdim=getMeshDimension();
2937 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2938 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2939 for(int i=0;i<spaceDim;i++)
2941 std::string info=coo->getInfoOnComponent(i);
2943 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2944 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
2945 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
2947 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2949 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2950 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2951 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
2952 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2953 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2954 (*it)->write(fid,meshName,mdim);
2955 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2959 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2960 * \return std::vector<int> - a sequence of the relative dimensions.
2962 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2964 std::vector<int> ret;
2966 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2967 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2974 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2975 * \return std::vector<int> - a sequence of the relative dimensions.
2977 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2979 std::vector<int> ret0=getNonEmptyLevels();
2980 if((const DataArrayDouble *) _coords)
2982 std::vector<int> ret(ret0.size()+1);
2984 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2990 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2992 std::vector<int> ret;
2993 const DataArrayInt *famCoo(_fam_coords);
2997 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2999 const MEDFileUMeshSplitL1 *cur(*it);
3001 if(cur->getFamilyField())
3007 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3009 std::vector<int> ret;
3010 if(_num_coords.isNotNull())
3013 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3015 const MEDFileUMeshSplitL1 *cur(*it);
3017 if(cur->getNumberField())
3023 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3025 std::vector<int> ret;
3026 const DataArrayAsciiChar *nameCoo(_name_coords);
3030 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3032 const MEDFileUMeshSplitL1 *cur(*it);
3034 if(cur->getNameField())
3041 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3042 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3043 * \param [in] fams - the name of the family of interest.
3044 * \return std::vector<int> - a sequence of the relative dimensions.
3046 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3048 std::vector<int> ret;
3049 std::vector<int> levs(getNonEmptyLevels());
3050 std::vector<int> famIds(getFamiliesIds(fams));
3051 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3052 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3058 * Returns all relative mesh levels (including nodes) where given families are defined.
3059 * \param [in] fams - the names of the families of interest.
3060 * \return std::vector<int> - a sequence of the relative dimensions.
3062 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3064 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
3065 const DataArrayInt *famCoords(_fam_coords);
3068 std::vector<int> famIds(getFamiliesIds(fams));
3069 if(famCoords->presenceOfValue(famIds))
3071 std::vector<int> ret(ret0.size()+1);
3073 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3080 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3082 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3083 if((const DataArrayInt *)_fam_coords)
3085 int val=_fam_coords->getMaxValue(tmp);
3086 ret=std::max(ret,std::abs(val));
3088 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3090 if((const MEDFileUMeshSplitL1 *)(*it))
3092 const DataArrayInt *da=(*it)->getFamilyField();
3095 int val=da->getMaxValue(tmp);
3096 ret=std::max(ret,std::abs(val));
3103 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3105 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3106 if((const DataArrayInt *)_fam_coords)
3108 int val=_fam_coords->getMaxValue(tmp);
3109 ret=std::max(ret,val);
3111 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3113 if((const MEDFileUMeshSplitL1 *)(*it))
3115 const DataArrayInt *da=(*it)->getFamilyField();
3118 int val=da->getMaxValue(tmp);
3119 ret=std::max(ret,val);
3126 int MEDFileUMesh::getMinFamilyIdInArrays() const
3128 int ret=std::numeric_limits<int>::max(),tmp=-1;
3129 if((const DataArrayInt *)_fam_coords)
3131 int val=_fam_coords->getMinValue(tmp);
3132 ret=std::min(ret,val);
3134 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3136 if((const MEDFileUMeshSplitL1 *)(*it))
3138 const DataArrayInt *da=(*it)->getFamilyField();
3141 int val=da->getMinValue(tmp);
3142 ret=std::min(ret,val);
3150 * Returns the dimension on cells in \a this mesh.
3151 * \return int - the mesh dimension.
3152 * \throw If there are no cells in this mesh.
3154 int MEDFileUMesh::getMeshDimension() const
3157 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3158 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3159 return (*it)->getMeshDimension()+lev;
3160 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3164 * Returns the space dimension of \a this mesh that is equal to number of components in
3165 * the node coordinates array.
3166 * \return int - the space dimension of \a this mesh.
3167 * \throw If the node coordinates array is not available.
3169 int MEDFileUMesh::getSpaceDimension() const
3171 const DataArrayDouble *coo=_coords;
3173 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3174 return coo->getNumberOfComponents();
3178 * Returns a string describing \a this mesh.
3179 * \return std::string - the mesh information string.
3181 std::string MEDFileUMesh::simpleRepr() const
3183 std::ostringstream oss;
3184 oss << MEDFileMesh::simpleRepr();
3185 const DataArrayDouble *coo=_coords;
3186 oss << "- The dimension of the space is ";
3187 static const char MSG1[]= "*** NO COORDS SET ***";
3188 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3190 oss << _coords->getNumberOfComponents() << std::endl;
3192 oss << MSG1 << std::endl;
3193 oss << "- Type of the mesh : UNSTRUCTURED\n";
3194 oss << "- Number of nodes : ";
3196 oss << _coords->getNumberOfTuples() << std::endl;
3198 oss << MSG1 << std::endl;
3199 std::size_t nbOfLev=_ms.size();
3200 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3201 for(std::size_t i=0;i<nbOfLev;i++)
3203 const MEDFileUMeshSplitL1 *lev=_ms[i];
3204 oss << " - Level #" << -((int) i) << " has dimension : ";
3207 oss << lev->getMeshDimension() << std::endl;
3208 lev->simpleRepr(oss);
3211 oss << MSG2 << std::endl;
3213 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3216 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3217 oss << "- Names of coordinates :" << std::endl;
3218 std::vector<std::string> vars=coo->getVarsOnComponent();
3219 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3220 oss << std::endl << "- Units of coordinates : " << std::endl;
3221 std::vector<std::string> units=coo->getUnitsOnComponent();
3222 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3224 oss << std::endl << std::endl;
3226 getEquivalencesRepr(oss);
3231 * Returns a full textual description of \a this mesh.
3232 * \return std::string - the string holding the mesh description.
3234 std::string MEDFileUMesh::advancedRepr() const
3236 return simpleRepr();
3240 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3241 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3242 * \return int - the number of entities.
3243 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3245 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3247 if(meshDimRelToMaxExt==1)
3249 if(!((const DataArrayDouble *)_coords))
3250 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3251 return _coords->getNumberOfTuples();
3253 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3257 * Returns the family field for mesh entities of a given dimension.
3258 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3259 * \return const DataArrayInt * - the family field. It is an array of ids of families
3260 * each mesh entity belongs to. It can be \c NULL.
3262 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3264 if(meshDimRelToMaxExt==1)
3266 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3267 return l1->getFamilyField();
3270 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3272 if(meshDimRelToMaxExt==1)
3274 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3275 return l1->getFamilyField();
3279 * Returns the optional numbers of mesh entities of a given dimension.
3280 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3281 * \return const DataArrayInt * - the array of the entity numbers.
3282 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3284 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3286 if(meshDimRelToMaxExt==1)
3288 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3289 return l1->getNumberField();
3292 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3294 if(meshDimRelToMaxExt==1)
3295 return _name_coords;
3296 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3297 return l1->getNameField();
3300 MCAuto<DataArrayInt> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3302 if(meshDimRelToMaxExt!=1)
3303 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3304 return _global_num_coords;
3308 * 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).
3310 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3311 * \param [in] gt - The input geometric type for which the part definition is requested.
3312 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3314 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3316 if(meshDimRelToMaxExt==1)
3317 return _part_coords;
3318 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3319 return l1->getPartDef(gt);
3322 int MEDFileUMesh::getNumberOfNodes() const
3324 const DataArrayDouble *coo(_coords);
3326 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3327 return coo->getNumberOfTuples();
3330 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3332 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3333 return l1->getNumberOfCells();
3336 bool MEDFileUMesh::hasImplicitPart() const
3341 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3343 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3346 void MEDFileUMesh::releaseImplicitPartIfAny() const
3350 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3352 std::size_t sz(st.getNumberOfItems());
3353 for(std::size_t i=0;i<sz;i++)
3355 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3356 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3357 if(st[i].getPflName().empty())
3358 m->computeNodeIdsAlg(nodesFetched);
3361 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3362 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3363 m2->computeNodeIdsAlg(nodesFetched);
3368 MEDFileMesh *MEDFileUMesh::cartesianize() const
3370 if(getAxisType()==AX_CART)
3373 return const_cast<MEDFileUMesh *>(this);
3377 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3378 const DataArrayDouble *coords(_coords);
3380 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3381 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3382 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3383 if((const MEDFileUMeshSplitL1 *)(*it))
3384 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3385 ret->_coords=coordsCart;
3386 ret->setAxisType(AX_CART);
3391 bool MEDFileUMesh::presenceOfStructureElements() const
3393 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3394 if((*it).isNotNull())
3399 void MEDFileUMesh::killStructureElements()
3405 * Returns the optional numbers of mesh entities of a given dimension transformed using
3406 * DataArrayInt::invertArrayN2O2O2N().
3407 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3408 * \return const DataArrayInt * - the array of the entity numbers transformed using
3409 * DataArrayInt::invertArrayN2O2O2N().
3410 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3412 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3414 if(meshDimRelToMaxExt==1)
3416 if(_num_coords.isNull())
3417 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3418 return _rev_num_coords;
3420 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3421 return l1->getRevNumberField();
3425 * Returns a pointer to the node coordinates array of \a this mesh \b without
3426 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3428 DataArrayDouble *MEDFileUMesh::getCoords() const
3431 MCAuto<DataArrayDouble> tmp(_coords);
3432 if((DataArrayDouble *)tmp)
3440 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3441 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3443 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3444 * \param [in] grp - the name of the group whose mesh entities are included in the
3446 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3447 * according to the optional numbers of entities, if available.
3448 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3449 * delete this mesh using decrRef() as it is no more needed.
3450 * \throw If the name of a nonexistent group is specified.
3451 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3453 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3456 synchronizeTinyInfoOnLeaves();
3457 std::vector<std::string> tmp(1);
3459 return getGroups(meshDimRelToMaxExt,tmp,renum);
3463 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3464 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3466 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3467 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3469 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3470 * according to the optional numbers of entities, if available.
3471 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3472 * delete this mesh using decrRef() as it is no more needed.
3473 * \throw If a name of a nonexistent group is present in \a grps.
3474 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3476 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3479 synchronizeTinyInfoOnLeaves();
3480 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3481 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3482 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3483 zeRet->setName(grps[0]);
3484 return zeRet.retn();
3488 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3489 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3491 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3492 * \param [in] fam - the name of the family whose mesh entities are included in the
3494 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3495 * according to the optional numbers of entities, if available.
3496 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3497 * delete this mesh using decrRef() as it is no more needed.
3498 * \throw If a name of a nonexistent family is present in \a grps.
3499 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3501 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3504 synchronizeTinyInfoOnLeaves();
3505 std::vector<std::string> tmp(1);
3507 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3511 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3512 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3514 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3515 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3517 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3518 * according to the optional numbers of entities, if available.
3519 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3520 * delete this mesh using decrRef() as it is no more needed.
3521 * \throw If a name of a nonexistent family is present in \a fams.
3522 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3524 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3527 synchronizeTinyInfoOnLeaves();
3528 if(meshDimRelToMaxExt==1)
3530 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3531 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3532 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3536 std::vector<int> famIds=getFamiliesIds(fams);
3537 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3538 MCAuto<MEDCouplingUMesh> zeRet;
3540 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3542 zeRet=l1->getFamilyPart(0,0,renum);
3543 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3544 zeRet->setName(fams[0]);
3545 return zeRet.retn();
3549 * Returns ids of mesh entities contained in given families of a given dimension.
3550 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3552 * \param [in] fams - the names of the families of interest.
3553 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3554 * returned instead of ids.
3555 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3556 * numbers, if available and required, of mesh entities of the families. The caller
3557 * is to delete this array using decrRef() as it is no more needed.
3558 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3560 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3562 std::vector<int> famIds=getFamiliesIds(fams);
3563 if(meshDimRelToMaxExt==1)
3565 if((const DataArrayInt *)_fam_coords)
3567 MCAuto<DataArrayInt> da;
3569 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3571 da=_fam_coords->findIdsEqualList(0,0);
3573 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3578 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3580 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3582 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3584 return l1->getFamilyPartArr(0,0,renum);
3588 * Returns a MEDCouplingUMesh of a given relative dimension.
3589 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3590 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3591 * To build a valid MEDCouplingUMesh from the returned one in this case,
3592 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3593 * \param [in] meshDimRelToMax - the relative dimension of interest.
3594 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3595 * optional numbers of mesh entities.
3596 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3597 * delete using decrRef() as it is no more needed.
3598 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3600 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3603 synchronizeTinyInfoOnLeaves();
3604 if(meshDimRelToMaxExt==1)
3608 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3609 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3610 umesh->setCoords(cc);
3611 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3612 umesh->setName(getName());
3616 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3617 return l1->getWholeMesh(renum);
3620 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3622 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3623 return l1->getDistributionOfTypes();
3627 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3628 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3629 * optional numbers of mesh entities.
3630 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3631 * delete using decrRef() as it is no more needed.
3632 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3634 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3636 return getMeshAtLevel(0,renum);
3640 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3641 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3642 * optional numbers of mesh entities.
3643 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3644 * delete using decrRef() as it is no more needed.
3645 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3647 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3649 return getMeshAtLevel(-1,renum);
3653 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3654 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3655 * optional numbers of mesh entities.
3656 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3657 * delete using decrRef() as it is no more needed.
3658 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3660 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3662 return getMeshAtLevel(-2,renum);
3666 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3667 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3668 * optional numbers of mesh entities.
3669 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3670 * delete using decrRef() as it is no more needed.
3671 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3673 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3675 return getMeshAtLevel(-3,renum);
3679 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3680 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3681 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3682 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3684 void MEDFileUMesh::forceComputationOfParts() const
3686 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3688 const MEDFileUMeshSplitL1 *elt(*it);
3690 elt->forceComputationOfParts();
3695 * This method returns a vector of mesh parts containing each exactly one geometric type.
3696 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3697 * This method is only for memory aware users.
3698 * The returned pointers are **NOT** new object pointer. No need to mange them.
3700 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3703 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3704 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3708 * This method returns the part of \a this having the geometric type \a gt.
3709 * If such part is not existing an exception will be thrown.
3710 * The returned pointer is **NOT** new object pointer. No need to mange it.
3712 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3715 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3716 int lev=(int)cm.getDimension()-getMeshDimension();
3717 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3718 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3722 * This method returns for each geo types in \a this number of cells with this geo type.
3723 * 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.
3724 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3726 * \sa getDistributionOfTypes
3728 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3730 std::vector< std::pair<int,int> > ret;
3731 std::vector<int> nel(getNonEmptyLevels());
3732 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3734 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3735 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3737 int nbCells(getNumberOfCellsWithType(*it1));
3738 ret.push_back(std::pair<int,int>(*it1,nbCells));
3741 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3746 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3747 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3749 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3751 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3752 return sp->getGeoTypes();
3755 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3757 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3758 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3759 return sp->getNumberOfCellsWithType(ct);
3763 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3764 * \param [in] gt - the geometric type for which the family field is asked.
3765 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3766 * delete using decrRef() as it is no more needed.
3767 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3769 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3771 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3772 int lev=(int)cm.getDimension()-getMeshDimension();
3773 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3774 return sp->extractFamilyFieldOnGeoType(gt);
3778 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3779 * \param [in] gt - the geometric type for which the number field is asked.
3780 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3781 * delete using decrRef() as it is no more needed.
3782 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3784 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3786 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3787 int lev=(int)cm.getDimension()-getMeshDimension();
3788 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3789 return sp->extractNumberFieldOnGeoType(gt);
3793 * This method returns for specified geometric type \a gt the relative level to \a this.
3794 * If the relative level is empty an exception will be thrown.
3796 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3798 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3799 int ret((int)cm.getDimension()-getMeshDimension());
3800 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3804 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3806 if(meshDimRelToMaxExt==1)
3807 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3808 if(meshDimRelToMaxExt>1)
3809 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3810 int tracucedRk=-meshDimRelToMaxExt;
3811 if(tracucedRk>=(int)_ms.size())
3812 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3813 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3814 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3815 return _ms[tracucedRk];
3818 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3820 if(meshDimRelToMaxExt==1)
3821 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3822 if(meshDimRelToMaxExt>1)
3823 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3824 int tracucedRk=-meshDimRelToMaxExt;
3825 if(tracucedRk>=(int)_ms.size())
3826 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3827 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3828 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3829 return _ms[tracucedRk];
3832 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3834 if(-meshDimRelToMax>=(int)_ms.size())
3835 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3837 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3839 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3841 int ref=(*it)->getMeshDimension();
3842 if(ref+i!=meshDim-meshDimRelToMax)
3843 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3849 * Sets the node coordinates array of \a this mesh.
3850 * \param [in] coords - the new node coordinates array.
3851 * \throw If \a coords == \c NULL.
3853 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3856 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3857 if(coords==(DataArrayDouble *)_coords)
3859 coords->checkAllocated();
3860 int nbOfTuples(coords->getNumberOfTuples());
3861 _coords.takeRef(coords);
3862 _fam_coords=DataArrayInt::New();
3863 _fam_coords->alloc(nbOfTuples,1);
3864 _fam_coords->fillWithZero();
3865 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3866 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3867 if((MEDFileUMeshSplitL1 *)(*it))
3868 (*it)->setCoords(coords);
3872 * Change coords without changing anything concerning families and numbering on nodes.
3874 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3877 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3878 if(coords==(DataArrayDouble *)_coords)
3880 coords->checkAllocated();
3881 int nbOfTuples(coords->getNumberOfTuples());
3882 if(_coords.isNull())
3889 int oldNbTuples(_coords->getNumberOfTuples());
3890 if(oldNbTuples!=nbOfTuples)
3891 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3895 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3896 if((MEDFileUMeshSplitL1 *)(*it))
3897 (*it)->setCoords(coords);
3901 * Removes all groups of a given dimension in \a this mesh.
3902 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3903 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3905 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3907 if(meshDimRelToMaxExt==1)
3909 if((DataArrayInt *)_fam_coords)
3910 _fam_coords->fillWithZero();
3913 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3914 l1->eraseFamilyField();
3919 * Removes all families with ids not present in the family fields of \a this mesh.
3921 void MEDFileUMesh::optimizeFamilies()
3923 std::vector<int> levs=getNonEmptyLevelsExt();
3924 std::set<int> allFamsIds;
3925 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3927 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3928 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3930 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3933 std::set<std::string> famNamesToKill;
3934 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3936 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3937 famNamesToKill.insert((*it).first);
3939 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3940 _families.erase(*it);
3941 std::vector<std::string> grpNamesToKill;
3942 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3944 std::vector<std::string> tmp;
3945 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3947 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3948 tmp.push_back(*it2);
3953 tmp.push_back((*it).first);
3955 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3960 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3961 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3962 * The boundary is built according to the following method:
3963 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3964 * coordinates array is extended).
3965 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3966 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3967 * might not be duplicated at all.
3968 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3969 * other side of the group is no more a neighbor)
3970 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3971 * bordering the newly created boundary use the newly computed nodes.
3972 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3973 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3975 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3976 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3978 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3979 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3980 * \sa clearNodeAndCellNumbers()
3982 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3983 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3985 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3986 typedef MCAuto<DataArrayInt> DAInt;
3988 std::vector<int> levs=getNonEmptyLevels();
3989 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3990 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
3991 MUMesh m0=getMeshAtLevel(0);
3992 MUMesh m1=getMeshAtLevel(-1);
3993 int nbNodes=m0->getNumberOfNodes();
3994 MUMesh m11=getGroup(-1,grpNameM1);
3995 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3996 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3997 DAInt nodeIdsToDuplicate(tmp00);
3998 DAInt cellsToModifyConn0(tmp11);
3999 DAInt cellsToModifyConn1(tmp22);
4000 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4001 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4002 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
4003 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4004 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4005 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4006 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4007 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
4008 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4009 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4010 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4011 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4012 DAInt grpIds=getGroupArr(-1,grpNameM1);
4013 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4014 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4015 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4016 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4017 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4018 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4019 m0->setCoords(tmp0->getCoords());
4020 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4021 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4022 m1->setCoords(m0->getCoords());
4023 _coords=m0->getCoords(); _coords->incrRef();
4024 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4025 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4026 DataArrayInt * duplCells;
4027 m1->areCellsIncludedIn(m11, 0, duplCells);
4028 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4029 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4030 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4031 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4032 DAInt szOfCellGrpOfSameType(tmp00);
4033 DAInt idInMsOfCellGrpOfSameType(tmp11);
4035 newm1->setName(getName());
4036 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
4038 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4039 DAInt newFam=DataArrayInt::New();
4040 newFam->alloc(newm1->getNumberOfCells(),1);
4041 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4042 // Positive ID for family of nodes, negative for all the rest.
4044 if (m1->getMeshDimension() == 0)
4045 idd=getMaxFamilyId()+1;
4047 idd=getMinFamilyId()-1;
4048 int globStart=0,start=0,end,globEnd;
4049 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4050 for(int i=0;i<nbOfChunks;i++)
4052 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4053 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4055 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4056 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4057 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4062 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4066 newm1->setCoords(getCoords());
4067 setMeshAtLevel(-1,newm1);
4068 setFamilyFieldArr(-1,newFam);
4069 std::string grpName2(grpNameM1); grpName2+="_dup";
4070 addFamily(grpName2,idd);
4071 addFamilyOnGrp(grpName2,grpName2);
4076 int newNbOfNodes=getCoords()->getNumberOfTuples();
4077 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
4078 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4079 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4083 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4085 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4086 it != _ms.end(); it++)
4089 (*it)->_rev_num = 0;
4091 nodesDuplicated=nodeIdsToDuplicate.retn();
4092 cellsModified=cellsToModifyConn0.retn();
4093 cellsNotModified=cellsToModifyConn1.retn();
4096 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4097 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4100 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4101 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4102 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4104 * \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.
4105 * 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.
4107 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4109 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4110 std::vector<int> levs=getNonEmptyLevels();
4112 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4113 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4116 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4118 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4119 std::vector<int> code1=m->getDistributionOfTypes();
4120 end=PutInThirdComponentOfCodeOffset(code1,start);
4121 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4122 bool hasChanged=m->unPolyze();
4123 DataArrayInt *fake=0;
4124 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4125 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4127 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4130 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4131 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4133 MCAuto<DataArrayInt> famField2,numField2;
4134 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4135 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4136 setMeshAtLevel(*it,m);
4137 std::vector<int> code2=m->getDistributionOfTypes();
4138 end=PutInThirdComponentOfCodeOffset(code2,start);
4139 newCode.insert(newCode.end(),code2.begin(),code2.end());
4141 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4145 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4146 setFamilyFieldArr(*it,newFamField);
4150 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4151 setRenumFieldArr(*it,newNumField);
4156 newCode.insert(newCode.end(),code1.begin(),code1.end());
4162 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4163 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4164 o2nRenumCell=o2nRenumCellRet.retn();
4169 /*! \cond HIDDEN_ITEMS */
4170 struct MEDLoaderAccVisit1
4172 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4173 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4174 int _new_nb_of_nodes;
4179 * 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.
4180 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4181 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4182 * -1 values in returned array means that the corresponding old node is no more used.
4184 * \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
4185 * is modified in \a this.
4186 * \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
4189 DataArrayInt *MEDFileUMesh::zipCoords()
4191 const DataArrayDouble *coo(getCoords());
4193 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4194 int nbOfNodes(coo->getNumberOfTuples());
4195 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4196 std::vector<int> neLevs(getNonEmptyLevels());
4197 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4199 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4200 if(zeLev->isMeshStoredSplitByType())
4202 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4203 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4205 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4209 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4210 mesh->computeNodeIdsAlg(nodeIdsInUse);
4213 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4214 if(nbrOfNodesInUse==nbOfNodes)
4215 return 0;//no need to update _part_coords
4216 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4217 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4218 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4219 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4220 MCAuto<DataArrayInt> newFamCoords;
4221 MCAuto<DataArrayAsciiChar> newNameCoords;
4222 if((const DataArrayInt *)_fam_coords)
4223 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4224 MCAuto<DataArrayInt> newNumCoords,newGlobalNumCoords;
4225 if(_num_coords.isNotNull())
4226 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4227 if(_global_num_coords.isNotNull())
4228 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4229 if(_name_coords.isNotNull())
4230 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4231 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4232 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4234 if((MEDFileUMeshSplitL1*)*it)
4236 (*it)->renumberNodesInConn(ret->begin());
4237 (*it)->setCoords(_coords);
4240 // updates _part_coords
4241 const PartDefinition *pc(_part_coords);
4244 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4245 _part_coords=tmpPD->composeWith(pc);
4251 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4252 * The extraction of \a this is specified by the extractDef \a input map.
4253 * This map tells for each level of cells, the cells kept in the extraction.
4255 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4256 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4258 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4260 std::vector<int> levs(getNonEmptyLevels());
4261 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4262 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4265 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4266 if((*it).second.isNull())
4267 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4270 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4272 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4273 throw INTERP_KERNEL::Exception(oss.str());
4275 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4276 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4277 mPart->computeNodeIdsAlg(fetchedNodes);
4279 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4283 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4285 * \return - a new reference of MEDFileUMesh
4286 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4288 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4290 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4291 std::vector<int> levs(getNonEmptyLevels());
4292 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4295 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4296 if((*it).second.isNull())
4297 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4300 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4302 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4303 throw INTERP_KERNEL::Exception(oss.str());
4305 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4306 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4307 ret->setMeshAtLevel((*it).first,mPart);
4308 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4311 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4312 ret->setFamilyFieldArr((*it).first,famPart);
4316 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4317 ret->setFamilyFieldArr((*it).first,numPart);
4320 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4321 if(it2!=extractDef.end())
4323 const DataArrayDouble *coo(ret->getCoords());
4325 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4326 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4327 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4328 ret->setCoords(cooPart);
4329 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4332 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4333 ret->setFamilyFieldArr(1,famPart);
4337 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4338 ret->setFamilyFieldArr(1,numPart);
4340 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4344 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4345 m->renumberNodesInConn(o2nNodes->begin());
4346 ret->setMeshAtLevel((*it3).first,m);
4353 * This method performs an extrusion along a path defined by \a m1D.
4354 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4355 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4356 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4357 * This method scans all levels in \a this
4358 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4360 * \param [in] m1D - the mesh defining the extrusion path.
4361 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4362 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4364 * \sa MEDCouplingUMesh::buildExtrudedMesh
4366 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4369 if(getMeshDimension()!=2)
4370 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4371 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4372 m1D->checkConsistencyLight();
4373 if(m1D->getMeshDimension()!=1)
4374 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4375 int nbRep(m1D->getNumberOfCells());
4376 std::vector<int> levs(getNonEmptyLevels());
4377 std::vector<std::string> grps(getGroupsNames());
4378 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4379 DataArrayDouble *coords(0);
4380 std::size_t nbOfLevsOut(levs.size()+1);
4381 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4382 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4384 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4385 item=item->clone(false);
4386 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4387 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4388 tmp->changeSpaceDimension(3+(*lev),0.);
4389 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4390 zeList.push_back(elt);
4392 coords=elt->getCoords();
4395 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4396 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4398 (*it)->setName(getName());
4399 (*it)->setCoords(coords);
4401 for(std::size_t ii=0;ii!=zeList.size();ii++)
4404 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4407 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4408 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4409 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4410 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4411 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4412 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4413 std::vector<const MEDCouplingUMesh *> elts(3);
4414 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4415 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4416 elt->setName(getName());
4419 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4420 ret->setMeshAtLevel(lev,elt);
4422 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4423 endLev=endLev->clone(false); endLev->setCoords(coords);
4424 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4425 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4426 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4427 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4428 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4429 endLev->setName(getName());
4430 ret->setMeshAtLevel(levs.back()-1,endLev);
4432 for(std::size_t ii=0;ii!=zeList.size();ii++)
4435 std::vector< MCAuto<DataArrayInt> > outGrps;
4436 std::vector< const DataArrayInt * > outGrps2;
4439 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4441 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4442 if(!grpArr->empty())
4444 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4445 int offset0(zeList[ii]->getNumberOfCells());
4446 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4447 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4448 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4449 grpArr2->setName(oss.str());
4450 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4451 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4452 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4453 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4458 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4460 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4461 if(!grpArr->empty())
4463 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4464 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4465 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4466 for(int iii=0;iii<nbRep;iii++)
4468 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4469 grpArrs2[iii]=grpArrs[iii];
4471 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4472 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4473 std::ostringstream grpName; grpName << *grp << "_extruded";
4474 grpArrExt->setName(grpName.str());
4475 outGrps.push_back(grpArrExt);
4476 outGrps2.push_back(grpArrExt);
4479 ret->setGroupsAtLevel(lev,outGrps2);
4481 std::vector< MCAuto<DataArrayInt> > outGrps;
4482 std::vector< const DataArrayInt * > outGrps2;
4483 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4485 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4486 if(grpArr1->empty())
4488 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4489 std::ostringstream grpName; grpName << *grp << "_top";
4490 grpArr2->setName(grpName.str());
4491 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4492 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4493 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4495 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4500 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4501 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4502 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4504 * \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
4505 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4506 * \param [in] eps - detection threshold for coordinates.
4507 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4509 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4511 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4514 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4515 int initialNbNodes(getNumberOfNodes());
4516 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4517 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4519 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4521 DataArrayDouble *zeCoords(m0->getCoords());
4522 ret->setMeshAtLevel(0,m0);
4523 std::vector<int> levs(getNonEmptyLevels());
4524 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4527 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4528 ret->setFamilyFieldArr(0,famFieldCpy);
4530 famField=getFamilyFieldAtLevel(1);
4533 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4534 fam->fillWithZero();
4535 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4536 ret->setFamilyFieldArr(1,fam);
4538 ret->copyFamGrpMapsFrom(*this);
4539 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4540 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4544 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4545 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4546 if(m1->getMeshDimension()!=0)
4549 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4550 }//kill unused notUsed var
4551 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4553 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4554 MCAuto<DataArrayInt> bSafe(b);
4557 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4558 throw INTERP_KERNEL::Exception(oss.str().c_str());
4560 b->applyLin(1,initialNbNodes);
4561 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4562 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4563 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4564 m1->renumberNodesInConn(renum->begin());
4566 m1->setCoords(zeCoords);
4567 ret->setMeshAtLevel(*lev,m1);
4568 famField=getFamilyFieldAtLevel(*lev);
4571 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4572 ret->setFamilyFieldArr(*lev,famFieldCpy);
4579 * This method converts all quadratic cells in \a this into linear cells.
4580 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4581 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4583 * \param [in] eps - detection threshold for coordinates.
4584 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4586 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4588 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4591 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4592 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4593 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4594 m0->convertQuadraticCellsToLinear();
4596 DataArrayDouble *zeCoords(m0->getCoords());
4597 ret->setMeshAtLevel(0,m0);
4598 std::vector<int> levs(getNonEmptyLevels());
4599 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4602 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4603 ret->setFamilyFieldArr(0,famFieldCpy);
4605 famField=getFamilyFieldAtLevel(1);
4608 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4609 ret->setFamilyFieldArr(1,fam);
4611 ret->copyFamGrpMapsFrom(*this);
4612 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4616 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4617 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4618 m1->convertQuadraticCellsToLinear();
4621 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4622 MCAuto<DataArrayInt> bSafe(b);
4625 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4626 throw INTERP_KERNEL::Exception(oss.str().c_str());
4628 m1->renumberNodesInConn(b->begin());
4629 m1->setCoords(zeCoords);
4630 ret->setMeshAtLevel(*lev,m1);
4631 famField=getFamilyFieldAtLevel(*lev);
4634 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4635 ret->setFamilyFieldArr(*lev,famFieldCpy);
4642 * Computes the symmetry of \a this.
4643 * \return a new object.
4645 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4647 MCAuto<MEDFileUMesh> ret(deepCopy());
4648 DataArrayDouble *myCoo(getCoords());
4651 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4652 ret->setCoordsForced(newCoo);
4657 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4660 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4661 std::size_t sz(meshes.size()),i(0);
4662 std::vector<const DataArrayDouble *> coos(sz);
4663 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4664 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4667 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4668 coos[i]=(*it)->getCoords();
4669 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4670 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4672 const MEDFileUMesh *ref(meshes[0]);
4673 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4674 std::vector<int> levs(ref->getNonEmptyLevels());
4675 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4676 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4677 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4678 std::map<std::string,int> map1;
4679 std::map<std::string, std::vector<std::string> > map2;
4680 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4682 if((*it)->getSpaceDimension()!=spaceDim)
4683 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4684 if((*it)->getMeshDimension()!=meshDim)
4685 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4686 if((*it)->getNonEmptyLevels()!=levs)
4687 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4688 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4690 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4691 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4692 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4693 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4695 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4696 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4697 map1[(*it3).first]=(*it3).second;
4698 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4699 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4700 map2[(*it4).first]=(*it4).second;
4702 // Easy part : nodes
4703 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4704 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4705 ret->setCoords(coo);
4706 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4708 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4709 ret->setFamilyFieldArr(1,fam_coo);
4711 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4713 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4714 ret->setRenumFieldArr(1,num_coo);
4717 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4719 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4720 if(it2==m_mesh.end())
4721 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4722 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4723 mesh->setCoords(coo); mesh->setName(ref->getName());
4724 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4725 ret->setMeshAtLevel(*it,mesh);
4726 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4727 if(it3!=m_fam.end())
4729 const std::vector<const DataArrayInt *>& fams((*it3).second);
4730 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4732 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4733 famm->renumberInPlace(renum->begin());
4734 ret->setFamilyFieldArr(*it,famm);
4737 if(it4!=m_renum.end())
4739 const std::vector<const DataArrayInt *>& renums((*it4).second);
4740 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4742 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4743 renumm->renumberInPlace(renum->begin());
4744 ret->setRenumFieldArr(*it,renumm);
4749 ret->setFamilyInfo(map1);
4750 ret->setGroupInfo(map2);
4751 ret->setName(ref->getName());
4755 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4757 if(getMeshDimension()!=3)
4758 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4759 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4760 if(m3D.isNull() || m2D.isNull())
4761 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4762 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4763 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4767 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4769 clearNonDiscrAttributes();
4770 forceComputationOfParts();
4771 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4772 std::vector<int> layer0;
4773 layer0.push_back(getAxisType());//0 i
4774 layer0.push_back(_order); //1 i
4775 layer0.push_back(_iteration);//2 i
4776 layer0.push_back(getSpaceDimension());//3 i
4777 tinyDouble.push_back(_time);//0 d
4778 tinyStr.push_back(_name);//0 s
4779 tinyStr.push_back(_desc_name);//1 s
4780 for(int i=0;i<getSpaceDimension();i++)
4781 tinyStr.push_back(_coords->getInfoOnComponent(i));
4782 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4783 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4785 tinyStr.push_back((*it).first);
4786 layer0.push_back((*it).second);
4788 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4789 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4791 layer0.push_back((int)(*it0).second.size());
4792 tinyStr.push_back((*it0).first);
4793 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4794 tinyStr.push_back(*it1);
4796 // sizeof(layer0)==4+aa+1+bb layer#0
4797 bigArrayD=_coords;// 0 bd
4798 bigArraysI.push_back(_fam_coords);// 0 bi
4799 bigArraysI.push_back(_num_coords);// 1 bi
4800 const PartDefinition *pd(_part_coords);
4802 layer0.push_back(-1);
4805 std::vector<int> tmp0;
4806 pd->serialize(tmp0,bigArraysI);
4807 tinyInt.push_back(tmp0.size());
4808 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4811 std::vector<int> layer1;
4812 std::vector<int> levs(getNonEmptyLevels());
4813 layer1.push_back((int)levs.size());// 0 i <- key
4814 layer1.insert(layer1.end(),levs.begin(),levs.end());
4815 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4817 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4818 lev->serialize(layer1,bigArraysI);
4820 // put layers all together.
4821 tinyInt.push_back(layer0.size());
4822 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4823 tinyInt.push_back(layer1.size());
4824 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4827 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4828 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4830 int sz0(tinyInt[0]);
4831 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4832 int sz1(tinyInt[sz0+1]);
4833 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4835 std::reverse(layer0.begin(),layer0.end());
4836 std::reverse(layer1.begin(),layer1.end());
4837 std::reverse(tinyDouble.begin(),tinyDouble.end());
4838 std::reverse(tinyStr.begin(),tinyStr.end());
4839 std::reverse(bigArraysI.begin(),bigArraysI.end());
4841 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4842 _order=layer0.back(); layer0.pop_back();
4843 _iteration=layer0.back(); layer0.pop_back();
4844 int spaceDim(layer0.back()); layer0.pop_back();
4845 _time=tinyDouble.back(); tinyDouble.pop_back();
4846 _name=tinyStr.back(); tinyStr.pop_back();
4847 _desc_name=tinyStr.back(); tinyStr.pop_back();
4848 _coords=bigArrayD; _coords->rearrange(spaceDim);
4849 for(int i=0;i<spaceDim;i++)
4851 _coords->setInfoOnComponent(i,tinyStr.back());
4854 int nbOfFams(layer0.back()); layer0.pop_back();
4856 for(int i=0;i<nbOfFams;i++)
4858 _families[tinyStr.back()]=layer0.back();
4859 tinyStr.pop_back(); layer0.pop_back();
4861 int nbGroups(layer0.back()); layer0.pop_back();
4863 for(int i=0;i<nbGroups;i++)
4865 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4866 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4867 std::vector<std::string> fams(nbOfFamsOnGrp);
4868 for(int j=0;j<nbOfFamsOnGrp;j++)
4870 fams[j]=tinyStr.back(); tinyStr.pop_back();
4872 _groups[grpName]=fams;
4874 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4875 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4877 int isPd(layer0.back()); layer0.pop_back();
4880 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4881 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4882 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4885 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4887 int nbLevs(layer1.back()); layer1.pop_back();
4888 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4890 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4891 _ms.resize(maxLev+1);
4892 for(int i=0;i<nbLevs;i++)
4896 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4901 * Adds a group of nodes to \a this mesh.
4902 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4903 * The ids should be sorted and different each other (MED file norm).
4905 * \warning this method can alter default "FAMILLE_ZERO" family.
4906 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4908 * \throw If the node coordinates array is not set.
4909 * \throw If \a ids == \c NULL.
4910 * \throw If \a ids->getName() == "".
4911 * \throw If \a ids does not respect the MED file norm.
4912 * \throw If a group with name \a ids->getName() already exists.
4914 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4916 const DataArrayDouble *coords(_coords);
4918 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4919 int nbOfNodes(coords->getNumberOfTuples());
4920 if(_fam_coords.isNull())
4921 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4923 addGroupUnderground(true,ids,_fam_coords);
4927 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4929 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4930 * The ids should be sorted and different each other (MED file norm).
4932 * \warning this method can alter default "FAMILLE_ZERO" family.
4933 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4935 * \throw If the node coordinates array is not set.
4936 * \throw If \a ids == \c NULL.
4937 * \throw If \a ids->getName() == "".
4938 * \throw If \a ids does not respect the MED file norm.
4939 * \throw If a group with name \a ids->getName() already exists.
4941 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4943 std::vector<int> levs(getNonEmptyLevelsExt());
4944 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4946 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4947 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4949 if(meshDimRelToMaxExt==1)
4950 { addNodeGroup(ids); return ; }
4951 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4952 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4953 addGroupUnderground(false,ids,fam);
4957 * Changes a name of a family specified by its id.
4958 * \param [in] id - the id of the family of interest.
4959 * \param [in] newFamName - the new family name.
4960 * \throw If no family with the given \a id exists.
4962 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4964 std::string oldName=getFamilyNameGivenId(id);
4965 _families.erase(oldName);
4966 _families[newFamName]=id;
4970 * Removes a mesh of a given dimension.
4971 * \param [in] meshDimRelToMax - the relative dimension of interest.
4972 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4974 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4976 std::vector<int> levSet=getNonEmptyLevels();
4977 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4978 if(it==levSet.end())
4979 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4980 int pos=(-meshDimRelToMax);
4985 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4986 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4987 * \param [in] m - the new mesh to set.
4988 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4990 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4991 * another node coordinates array.
4992 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4993 * to the existing meshes of other levels of \a this mesh.
4995 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4997 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4998 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5002 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5003 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5004 * \param [in] m - the new mesh to set.
5005 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5006 * writing \a this mesh in a MED file.
5007 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5009 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5010 * another node coordinates array.
5011 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5012 * to the existing meshes of other levels of \a this mesh.
5014 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5016 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5017 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5020 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5022 dealWithTinyInfo(m);
5023 std::vector<int> levSet=getNonEmptyLevels();
5024 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5026 if((DataArrayDouble *)_coords==0)
5028 DataArrayDouble *c=m->getCoords();
5033 if(m->getCoords()!=_coords)
5034 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5035 int sz=(-meshDimRelToMax)+1;
5036 if(sz>=(int)_ms.size())
5038 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5042 return _ms[-meshDimRelToMax];
5046 * This method allows to set at once the content of different levels in \a this.
5047 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5049 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5050 * \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.
5051 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5053 * \throw If \a there is a null pointer in \a ms.
5054 * \sa MEDFileUMesh::setMeshAtLevel
5056 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5060 const MEDCouplingUMesh *mRef=ms[0];
5062 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5063 std::string name(mRef->getName());
5064 const DataArrayDouble *coo(mRef->getCoords());
5067 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5069 const MEDCouplingUMesh *cur(*it);
5071 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5072 if(coo!=cur->getCoords())
5073 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5074 int mdim=cur->getMeshDimension();
5075 zeDim=std::max(zeDim,mdim);
5076 if(s.find(mdim)!=s.end())
5077 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5079 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5081 int mdim=(*it)->getMeshDimension();
5082 setName((*it)->getName());
5083 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5089 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5090 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5091 * The given meshes must share the same node coordinates array.
5092 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5093 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5094 * create in \a this mesh.
5095 * \throw If \a ms is empty.
5096 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5097 * to the existing meshes of other levels of \a this mesh.
5098 * \throw If the meshes in \a ms do not share the same node coordinates array.
5099 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5100 * of the given meshes.
5101 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5102 * \throw If names of some meshes in \a ms are equal.
5103 * \throw If \a ms includes a mesh with an empty name.
5105 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5108 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5109 int sz=(-meshDimRelToMax)+1;
5110 if(sz>=(int)_ms.size())
5112 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5113 DataArrayDouble *coo=checkMultiMesh(ms);
5114 if((DataArrayDouble *)_coords==0)
5120 if((DataArrayDouble *)_coords!=coo)
5121 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5122 std::vector<DataArrayInt *> corr;
5123 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5124 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5125 setMeshAtLevel(meshDimRelToMax,m,renum);
5126 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5127 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5131 * Creates groups at a given level in \a this mesh from a sequence of
5132 * meshes each representing a group.
5133 * The given meshes must share the same node coordinates array.
5134 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5135 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5136 * create in \a this mesh.
5137 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5139 * \throw If \a ms is empty.
5140 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5141 * to the existing meshes of other levels of \a this mesh.
5142 * \throw If the meshes in \a ms do not share the same node coordinates array.
5143 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5144 * of the given meshes.
5145 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5146 * \throw If names of some meshes in \a ms are equal.
5147 * \throw If \a ms includes a mesh with an empty name.
5149 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5152 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5153 int sz=(-meshDimRelToMax)+1;
5154 if(sz>=(int)_ms.size())
5156 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5157 DataArrayDouble *coo=checkMultiMesh(ms);
5158 if((DataArrayDouble *)_coords==0)
5164 if((DataArrayDouble *)_coords!=coo)
5165 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5166 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5167 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5169 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5171 DataArrayInt *arr=0;
5172 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5176 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5177 throw INTERP_KERNEL::Exception(oss.str().c_str());
5180 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5181 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5184 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5186 const DataArrayDouble *ret=ms[0]->getCoords();
5187 int mdim=ms[0]->getMeshDimension();
5188 for(unsigned int i=1;i<ms.size();i++)
5190 ms[i]->checkConsistencyLight();
5191 if(ms[i]->getCoords()!=ret)
5192 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5193 if(ms[i]->getMeshDimension()!=mdim)
5194 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5196 return const_cast<DataArrayDouble *>(ret);
5200 * Sets the family field of a given relative dimension.
5201 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5202 * the family field is set.
5203 * \param [in] famArr - the array of the family field.
5204 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5205 * \throw If \a famArr has an invalid size.
5207 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5209 if(meshDimRelToMaxExt==1)
5216 DataArrayDouble *coo(_coords);
5218 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5219 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5220 _fam_coords.takeRef(famArr);
5223 if(meshDimRelToMaxExt>1)
5224 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5225 int traducedRk=-meshDimRelToMaxExt;
5226 if(traducedRk>=(int)_ms.size())
5227 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5228 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5229 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5230 return _ms[traducedRk]->setFamilyArr(famArr);
5234 * Sets the optional numbers of mesh entities of a given dimension.
5235 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5236 * \param [in] renumArr - the array of the numbers.
5237 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5238 * \throw If \a renumArr has an invalid size.
5240 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5242 if(meshDimRelToMaxExt==1)
5246 _num_coords.nullify();
5247 _rev_num_coords.nullify();
5250 if(_coords.isNull())
5251 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5252 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5253 _num_coords.takeRef(renumArr);
5257 if(meshDimRelToMaxExt>1)
5258 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5259 int traducedRk=-meshDimRelToMaxExt;
5260 if(traducedRk>=(int)_ms.size())
5261 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5262 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5263 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5264 return _ms[traducedRk]->setRenumArr(renumArr);
5268 * Sets the optional names of mesh entities of a given dimension.
5269 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5270 * \param [in] nameArr - the array of the names.
5271 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5272 * \throw If \a nameArr has an invalid size.
5274 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5276 if(meshDimRelToMaxExt==1)
5283 DataArrayDouble *coo(_coords);
5285 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5286 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5287 _name_coords.takeRef(nameArr);
5290 if(meshDimRelToMaxExt>1)
5291 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5292 int traducedRk=-meshDimRelToMaxExt;
5293 if(traducedRk>=(int)_ms.size())
5294 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5295 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5296 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5297 return _ms[traducedRk]->setNameArr(nameArr);
5300 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5302 if(meshDimRelToMaxExt!=1)
5303 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5305 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5306 _global_num_coords.takeRef(globalNumArr);
5309 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5311 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5312 if((const MEDFileUMeshSplitL1 *)(*it))
5313 (*it)->synchronizeTinyInfo(*this);
5317 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5319 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5321 DataArrayInt *arr=_fam_coords;
5323 arr->changeValue(oldId,newId);
5324 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5326 MEDFileUMeshSplitL1 *sp=(*it);
5329 sp->changeFamilyIdArr(oldId,newId);
5334 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5336 std::list< MCAuto<DataArrayInt> > ret;
5337 const DataArrayInt *da(_fam_coords);
5339 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5340 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5342 const MEDFileUMeshSplitL1 *elt(*it);
5345 da=elt->getFamilyField();
5347 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5353 void MEDFileUMesh::computeRevNum() const
5355 if(_num_coords.isNotNull())
5358 int maxValue=_num_coords->getMaxValue(pos);
5359 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5363 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5365 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5368 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5370 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5371 ret.push_back((const DataArrayInt *)_fam_nodes);
5372 ret.push_back((const DataArrayInt *)_num_nodes);
5373 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5374 ret.push_back((const DataArrayInt *)_fam_cells);
5375 ret.push_back((const DataArrayInt *)_num_cells);
5376 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5377 ret.push_back((const DataArrayInt *)_fam_faces);
5378 ret.push_back((const DataArrayInt *)_num_faces);
5379 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5380 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5381 ret.push_back((const DataArrayInt *)_rev_num_cells);
5382 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5386 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5388 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5389 if((const DataArrayInt *)_fam_nodes)
5391 int val=_fam_nodes->getMaxValue(tmp);
5392 ret=std::max(ret,std::abs(val));
5394 if((const DataArrayInt *)_fam_cells)
5396 int val=_fam_cells->getMaxValue(tmp);
5397 ret=std::max(ret,std::abs(val));
5399 if((const DataArrayInt *)_fam_faces)
5401 int val=_fam_faces->getMaxValue(tmp);
5402 ret=std::max(ret,std::abs(val));
5407 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5409 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5410 if((const DataArrayInt *)_fam_nodes)
5412 int val=_fam_nodes->getMaxValue(tmp);
5413 ret=std::max(ret,val);
5415 if((const DataArrayInt *)_fam_cells)
5417 int val=_fam_cells->getMaxValue(tmp);
5418 ret=std::max(ret,val);
5420 if((const DataArrayInt *)_fam_faces)
5422 int val=_fam_faces->getMaxValue(tmp);
5423 ret=std::max(ret,val);
5428 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5430 int ret=std::numeric_limits<int>::max(),tmp=-1;
5431 if((const DataArrayInt *)_fam_nodes)
5433 int val=_fam_nodes->getMinValue(tmp);
5434 ret=std::min(ret,val);
5436 if((const DataArrayInt *)_fam_cells)
5438 int val=_fam_cells->getMinValue(tmp);
5439 ret=std::min(ret,val);
5441 if((const DataArrayInt *)_fam_faces)
5443 int val=_fam_faces->getMinValue(tmp);
5444 ret=std::min(ret,val);
5449 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5451 if(!MEDFileMesh::isEqual(other,eps,what))
5453 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5456 what="Mesh types differ ! This is structured and other is NOT !";
5459 const DataArrayInt *famc1=_fam_nodes;
5460 const DataArrayInt *famc2=otherC->_fam_nodes;
5461 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5463 what="Mismatch of families arr on nodes ! One is defined and not other !";
5468 bool ret=famc1->isEqual(*famc2);
5471 what="Families arr on nodes differ !";
5476 famc2=otherC->_fam_cells;
5477 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5479 what="Mismatch of families arr on cells ! One is defined and not other !";
5484 bool ret=famc1->isEqual(*famc2);
5487 what="Families arr on cells differ !";
5492 famc2=otherC->_fam_faces;
5493 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5495 what="Mismatch of families arr on faces ! One is defined and not other !";
5500 bool ret=famc1->isEqual(*famc2);
5503 what="Families arr on faces differ !";
5508 famc2=otherC->_num_nodes;
5509 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5511 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5516 bool ret=famc1->isEqual(*famc2);
5519 what="Numbering arr on nodes differ !";
5524 famc2=otherC->_num_cells;
5525 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5527 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5532 bool ret=famc1->isEqual(*famc2);
5535 what="Numbering arr on cells differ !";
5540 famc2=otherC->_num_faces;
5541 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5543 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5548 bool ret=famc1->isEqual(*famc2);
5551 what="Numbering arr on faces differ !";
5555 const DataArrayAsciiChar *d1=_names_cells;
5556 const DataArrayAsciiChar *d2=otherC->_names_cells;
5557 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5559 what="Mismatch of naming arr on cells ! One is defined and not other !";
5564 bool ret=d1->isEqual(*d2);
5567 what="Naming arr on cells differ !";
5572 d2=otherC->_names_faces;
5573 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5575 what="Mismatch of naming arr on faces ! One is defined and not other !";
5580 bool ret=d1->isEqual(*d2);
5583 what="Naming arr on faces differ !";
5588 d2=otherC->_names_nodes;
5589 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5591 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5596 bool ret=d1->isEqual(*d2);
5599 what="Naming arr on nodes differ !";
5606 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5608 MEDFileMesh::clearNonDiscrAttributes();
5609 const DataArrayInt *tmp=_fam_nodes;
5611 (const_cast<DataArrayInt *>(tmp))->setName("");
5614 (const_cast<DataArrayInt *>(tmp))->setName("");
5617 (const_cast<DataArrayInt *>(tmp))->setName("");
5620 (const_cast<DataArrayInt *>(tmp))->setName("");
5623 (const_cast<DataArrayInt *>(tmp))->setName("");
5626 (const_cast<DataArrayInt *>(tmp))->setName("");
5630 * Returns ids of mesh entities contained in given families of a given dimension.
5631 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5633 * \param [in] fams - the names of the families of interest.
5634 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5635 * returned instead of ids.
5636 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5637 * numbers, if available and required, of mesh entities of the families. The caller
5638 * is to delete this array using decrRef() as it is no more needed.
5639 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5641 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5643 std::vector<int> famIds(getFamiliesIds(fams));
5644 switch(meshDimRelToMaxExt)
5648 if((const DataArrayInt *)_fam_nodes)
5650 MCAuto<DataArrayInt> da;
5652 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5654 da=_fam_nodes->findIdsEqualList(0,0);
5656 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5661 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5666 if((const DataArrayInt *)_fam_cells)
5668 MCAuto<DataArrayInt> da;
5670 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5672 da=_fam_cells->findIdsEqualList(0,0);
5674 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5679 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5684 if((const DataArrayInt *)_fam_faces)
5686 MCAuto<DataArrayInt> da;
5688 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5690 da=_fam_faces->findIdsEqualList(0,0);
5692 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5697 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5701 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5703 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5707 * Sets the family field of a given relative dimension.
5708 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5709 * the family field is set.
5710 * \param [in] famArr - the array of the family field.
5711 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5712 * \throw If \a famArr has an invalid size.
5713 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5715 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5717 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5719 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5720 switch(meshDimRelToMaxExt)
5724 int nbCells(mesh->getNumberOfCells());
5726 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5732 int nbNodes(mesh->getNumberOfNodes());
5734 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5740 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5742 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5747 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5754 * Sets the optional numbers of mesh entities of a given dimension.
5755 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5756 * \param [in] renumArr - the array of the numbers.
5757 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5758 * \throw If \a renumArr has an invalid size.
5759 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5761 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5763 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5765 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5766 switch(meshDimRelToMaxExt)
5770 int nbCells=mesh->getNumberOfCells();
5771 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5772 _num_cells=renumArr;
5777 int nbNodes=mesh->getNumberOfNodes();
5778 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5779 _num_nodes=renumArr;
5784 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5785 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5786 _num_faces=renumArr;
5790 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5793 renumArr->incrRef();
5797 * Sets the optional names of mesh entities of a given dimension.
5798 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5799 * \param [in] nameArr - the array of the names.
5800 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5801 * \throw If \a nameArr has an invalid size.
5803 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5805 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5807 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5808 switch(meshDimRelToMaxExt)
5812 int nbCells=mesh->getNumberOfCells();
5813 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5814 _names_cells=nameArr;
5819 int nbNodes=mesh->getNumberOfNodes();
5820 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5821 _names_nodes=nameArr;
5826 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5827 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5828 _names_cells=nameArr;
5831 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5837 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5839 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
5843 * Adds a group of nodes to \a this mesh.
5844 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5845 * The ids should be sorted and different each other (MED file norm).
5847 * \warning this method can alter default "FAMILLE_ZERO" family.
5848 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5850 * \throw If the node coordinates array is not set.
5851 * \throw If \a ids == \c NULL.
5852 * \throw If \a ids->getName() == "".
5853 * \throw If \a ids does not respect the MED file norm.
5854 * \throw If a group with name \a ids->getName() already exists.
5856 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5862 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5864 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5865 * The ids should be sorted and different each other (MED file norm).
5867 * \warning this method can alter default "FAMILLE_ZERO" family.
5868 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5870 * \throw If the node coordinates array is not set.
5871 * \throw If \a ids == \c NULL.
5872 * \throw If \a ids->getName() == "".
5873 * \throw If \a ids does not respect the MED file norm.
5874 * \throw If a group with name \a ids->getName() already exists.
5876 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5878 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5879 addGroupUnderground(false,ids,fam);
5884 * Returns the family field for mesh entities of a given dimension.
5885 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5886 * \return const DataArrayInt * - the family field. It is an array of ids of families
5887 * each mesh entity belongs to. It can be \c NULL.
5888 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5890 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5892 switch(meshDimRelToMaxExt)
5901 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5906 * Returns the family field for mesh entities of a given dimension.
5907 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5908 * \return const DataArrayInt * - the family field. It is an array of ids of families
5909 * each mesh entity belongs to. It can be \c NULL.
5910 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5912 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5914 switch(meshDimRelToMaxExt)
5923 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5928 * Returns the optional numbers of mesh entities of a given dimension.
5929 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5930 * \return const DataArrayInt * - the array of the entity numbers.
5931 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5932 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5934 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5936 switch(meshDimRelToMaxExt)
5945 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5950 * Returns the optional numbers of mesh entities of a given dimension transformed using
5951 * DataArrayInt::invertArrayN2O2O2N().
5952 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5953 * \return const DataArrayInt * - the array of the entity numbers transformed using
5954 * DataArrayInt::invertArrayN2O2O2N().
5955 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5956 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5958 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5960 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5961 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5962 if(meshDimRelToMaxExt==0)
5964 if((const DataArrayInt *)_num_cells)
5967 int maxValue=_num_cells->getMaxValue(pos);
5968 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5969 return _rev_num_cells;
5972 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5976 if((const DataArrayInt *)_num_nodes)
5979 int maxValue=_num_nodes->getMaxValue(pos);
5980 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5981 return _rev_num_nodes;
5984 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5988 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5990 switch(meshDimRelToMaxExt)
5993 return _names_cells;
5995 return _names_nodes;
5997 return _names_faces;
5999 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6003 MCAuto<DataArrayInt> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6005 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6009 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6010 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6012 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6014 std::vector<int> ret(1);
6019 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6020 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6022 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6024 std::vector<int> ret(2);
6030 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6032 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6034 std::vector<int> ret;
6035 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6046 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6048 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6050 std::vector<int> ret;
6051 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6062 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6064 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6066 std::vector<int> ret;
6067 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6078 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6080 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
6082 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6086 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
6088 DataArrayInt *arr=_fam_nodes;
6090 arr->changeValue(oldId,newId);
6093 arr->changeValue(oldId,newId);
6096 arr->changeValue(oldId,newId);
6099 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6101 std::list< MCAuto<DataArrayInt> > ret;
6102 const DataArrayInt *da(_fam_nodes);
6104 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6107 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6110 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6114 void MEDFileStructuredMesh::deepCpyAttributes()
6116 if((const DataArrayInt*)_fam_nodes)
6117 _fam_nodes=_fam_nodes->deepCopy();
6118 if((const DataArrayInt*)_num_nodes)
6119 _num_nodes=_num_nodes->deepCopy();
6120 if((const DataArrayAsciiChar*)_names_nodes)
6121 _names_nodes=_names_nodes->deepCopy();
6122 if((const DataArrayInt*)_fam_cells)
6123 _fam_cells=_fam_cells->deepCopy();
6124 if((const DataArrayInt*)_num_cells)
6125 _num_cells=_num_cells->deepCopy();
6126 if((const DataArrayAsciiChar*)_names_cells)
6127 _names_cells=_names_cells->deepCopy();
6128 if((const DataArrayInt*)_fam_faces)
6129 _fam_faces=_fam_faces->deepCopy();
6130 if((const DataArrayInt*)_num_faces)
6131 _num_faces=_num_faces->deepCopy();
6132 if((const DataArrayAsciiChar*)_names_faces)
6133 _names_faces=_names_faces->deepCopy();
6134 if((const DataArrayInt*)_rev_num_nodes)
6135 _rev_num_nodes=_rev_num_nodes->deepCopy();
6136 if((const DataArrayInt*)_rev_num_cells)
6137 _rev_num_cells=_rev_num_cells->deepCopy();
6141 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6143 * \return a pointer to cartesian mesh that need to be managed by the caller.
6144 * \warning the returned pointer has to be managed by the caller.
6148 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6149 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6150 * \param [in] renum - it must be \c false.
6151 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6152 * delete using decrRef() as it is no more needed.
6154 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6158 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6159 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6160 switch(meshDimRelToMax)
6166 return const_cast<MEDCouplingStructuredMesh *>(m);
6171 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6172 buildMinusOneImplicitPartIfNeeded();
6173 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6179 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6183 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6185 std::vector<int> ret;
6186 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6187 if(famCells && famCells->presenceOfValue(ret))
6189 if(famFaces && famFaces->presenceOfValue(ret))
6194 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6196 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6197 const DataArrayInt *famNodes(_fam_nodes);
6198 if(famNodes && famNodes->presenceOfValue(ret))
6204 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6205 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6206 * \return int - the number of entities.
6207 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6209 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6211 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6213 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6214 switch(meshDimRelToMaxExt)
6217 return cmesh->getNumberOfCells();
6219 return cmesh->getNumberOfNodes();
6221 return cmesh->getNumberOfCellsOfSubLevelMesh();
6223 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6227 int MEDFileStructuredMesh::getNumberOfNodes() const
6229 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6231 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6232 return cmesh->getNumberOfNodes();
6235 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6237 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6239 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6240 switch(meshDimRelToMaxExt)
6243 return cmesh->getNumberOfCells();
6245 return cmesh->getNumberOfCellsOfSubLevelMesh();
6247 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6251 bool MEDFileStructuredMesh::hasImplicitPart() const
6257 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6259 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6261 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6262 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6265 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6266 if(cm.getReverseExtrudedType()!=gt)
6267 throw INTERP_KERNEL::Exception(MSG);
6268 buildImplicitPart();
6269 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6273 if(gt!=zeFaceMesh->getCellModelEnum())
6274 throw INTERP_KERNEL::Exception(MSG);
6275 return zeFaceMesh->getNumberOfCells();
6279 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6281 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6283 buildImplicitPart();
6286 void MEDFileStructuredMesh::buildImplicitPart() const
6288 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6290 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6291 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6294 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6296 _faces_if_necessary=0;
6300 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6301 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6303 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6305 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6308 return _faces_if_necessary;
6311 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6313 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6315 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6316 switch(meshDimRelToMax)
6320 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6325 int mdim(cmesh->getMeshDimension());
6327 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6328 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6332 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6336 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6338 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6341 return getNumberOfCellsAtLevel(0);
6344 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6346 if(st.getNumberOfItems()!=1)
6347 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 !");
6348 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6349 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6350 if(getNumberOfNodes()!=(int)nodesFetched.size())
6351 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6352 if(st[0].getPflName().empty())
6354 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6357 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6358 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6359 int sz(nodesFetched.size());
6360 for(const int *work=arr->begin();work!=arr->end();work++)
6362 std::vector<int> conn;
6363 cmesh->getNodeIdsOfCell(*work,conn);
6364 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6365 if(*it>=0 && *it<sz)
6366 nodesFetched[*it]=true;
6368 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6372 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6374 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6378 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6379 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6381 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6382 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6384 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6387 if(!mrs || mrs->isCellFamilyFieldReading())
6389 famCells=DataArrayInt::New();
6390 famCells->alloc(nbOfElt,1);
6391 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6394 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6397 if(!mrs || mrs->isCellNumFieldReading())
6399 numCells=DataArrayInt::New();
6400 numCells->alloc(nbOfElt,1);
6401 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6404 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6407 if(!mrs || mrs->isCellNameFieldReading())
6409 namesCells=DataArrayAsciiChar::New();
6410 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6411 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6412 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6417 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6419 setName(strm->getName());
6420 setDescription(strm->getDescription());
6421 setUnivName(strm->getUnivName());
6422 setIteration(strm->getIteration());
6423 setOrder(strm->getOrder());
6424 setTimeValue(strm->getTime());
6425 setTimeUnit(strm->getTimeUnit());
6426 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6427 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6428 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6431 if(!mrs || mrs->isNodeFamilyFieldReading())
6433 int nbNodes(getNumberOfNodes());
6435 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6436 _fam_nodes=DataArrayInt::New();
6437 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6438 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...
6439 _fam_nodes->fillWithZero();
6440 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6443 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6446 if(!mrs || mrs->isNodeNumFieldReading())
6448 _num_nodes=DataArrayInt::New();
6449 _num_nodes->alloc(nbOfElt,1);
6450 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6453 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6456 if(!mrs || mrs->isNodeNameFieldReading())
6458 _names_nodes=DataArrayAsciiChar::New();
6459 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6460 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6461 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6464 int meshDim(getStructuredMesh()->getMeshDimension());
6465 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6467 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6470 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6472 int meshDim(getStructuredMesh()->getMeshDimension());
6473 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6475 if((const DataArrayInt *)_fam_cells)
6476 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6477 if((const DataArrayInt *)_fam_faces)
6478 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6479 if((const DataArrayInt *)_fam_nodes)
6480 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6481 if((const DataArrayInt *)_num_cells)
6482 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6483 if((const DataArrayInt *)_num_faces)
6484 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6485 if((const DataArrayInt *)_num_nodes)
6486 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6487 if((const DataArrayAsciiChar *)_names_cells)
6489 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6491 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6492 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6493 throw INTERP_KERNEL::Exception(oss.str().c_str());
6495 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6497 if((const DataArrayAsciiChar *)_names_faces)
6499 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6501 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6502 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6503 throw INTERP_KERNEL::Exception(oss.str().c_str());
6505 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6507 if((const DataArrayAsciiChar *)_names_nodes)
6509 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6511 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6512 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6513 throw INTERP_KERNEL::Exception(oss.str().c_str());
6515 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6518 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6522 * Returns an empty instance of MEDFileCMesh.
6523 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6524 * mesh using decrRef() as it is no more needed.
6526 MEDFileCMesh *MEDFileCMesh::New()
6528 return new MEDFileCMesh;
6532 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6533 * file. The first mesh in the file is loaded.
6534 * \param [in] fileName - the name of MED file to read.
6535 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6536 * mesh using decrRef() as it is no more needed.
6537 * \throw If the file is not readable.
6538 * \throw If there is no meshes in the file.
6539 * \throw If the mesh in the file is not a Cartesian one.
6541 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6543 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6544 return New(fid,mrs);
6547 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6549 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6553 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6554 * file. The mesh to load is specified by its name and numbers of a time step and an
6556 * \param [in] fileName - the name of MED file to read.
6557 * \param [in] mName - the name of the mesh to read.
6558 * \param [in] dt - the number of a time step.
6559 * \param [in] it - the number of an iteration.
6560 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6561 * mesh using decrRef() as it is no more needed.
6562 * \throw If the file is not readable.
6563 * \throw If there is no mesh with given attributes in the file.
6564 * \throw If the mesh in the file is not a Cartesian one.
6566 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6568 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6569 return New(fid,mName,dt,it,mrs);
6572 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6574 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6577 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6579 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6582 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6584 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6585 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6590 * Returns the dimension on cells in \a this mesh.
6591 * \return int - the mesh dimension.
6592 * \throw If there are no cells in this mesh.
6594 int MEDFileCMesh::getMeshDimension() const
6596 if(!((const MEDCouplingCMesh*)_cmesh))
6597 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6598 return _cmesh->getMeshDimension();
6602 * Returns the dimension on nodes in \a this mesh.
6603 * \return int - the space dimension.
6604 * \throw If there are no cells in this mesh.
6606 int MEDFileCMesh::getSpaceDimension() const
6608 if(!((const MEDCouplingCMesh*)_cmesh))
6609 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6610 return _cmesh->getSpaceDimension();
6614 * Returns a string describing \a this mesh.
6615 * \return std::string - the mesh information string.
6617 std::string MEDFileCMesh::simpleRepr() const
6619 return MEDFileStructuredMesh::simpleRepr();
6623 * Returns a full textual description of \a this mesh.
6624 * \return std::string - the string holding the mesh description.
6626 std::string MEDFileCMesh::advancedRepr() const
6628 return simpleRepr();
6631 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6633 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6637 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6639 return new MEDFileCMesh;
6642 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6644 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6645 ret->deepCpyEquivalences(*this);
6646 if((const MEDCouplingCMesh*)_cmesh)
6647 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6648 ret->deepCpyAttributes();
6653 * Checks if \a this and another mesh are equal.
6654 * \param [in] other - the mesh to compare with.
6655 * \param [in] eps - a precision used to compare real values.
6656 * \param [in,out] what - the string returning description of unequal data.
6657 * \return bool - \c true if the meshes are equal, \c false, else.
6659 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6661 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6663 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6666 what="Mesh types differ ! This is cartesian and other is NOT !";
6669 clearNonDiscrAttributes();
6670 otherC->clearNonDiscrAttributes();
6671 const MEDCouplingCMesh *coo1=_cmesh;
6672 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6673 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6675 what="Mismatch of cartesian meshes ! One is defined and not other !";
6680 bool ret=coo1->isEqual(coo2,eps);
6683 what="cartesian meshes differ !";
6691 * Clears redundant attributes of incorporated data arrays.
6693 void MEDFileCMesh::clearNonDiscrAttributes() const
6695 MEDFileStructuredMesh::clearNonDiscrAttributes();
6696 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6699 MEDFileCMesh::MEDFileCMesh()
6703 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6706 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6708 catch(INTERP_KERNEL::Exception& e)
6713 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6715 MEDCoupling::MEDCouplingMeshType meshType;
6718 MEDCoupling::MEDCouplingAxisType axType;
6719 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6720 if(meshType!=CARTESIAN)
6722 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6723 throw INTERP_KERNEL::Exception(oss.str().c_str());
6725 MEDFileCMeshL2 loaderl2;
6726 loaderl2.loadAll(fid,mid,mName,dt,it);
6727 setAxisType(axType);
6728 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6731 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6735 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6736 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6738 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6740 synchronizeTinyInfoOnLeaves();
6744 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6746 synchronizeTinyInfoOnLeaves();
6751 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6752 * \param [in] m - the new MEDCouplingCMesh to refer to.
6753 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6756 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6758 dealWithTinyInfo(m);
6764 MEDFileMesh *MEDFileCMesh::cartesianize() const
6766 if(getAxisType()==AX_CART)
6769 return const_cast<MEDFileCMesh *>(this);
6773 const MEDCouplingCMesh *cmesh(getMesh());
6775 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6776 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6777 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6778 clmesh->setCoords(coords);
6779 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6780 ret->MEDFileStructuredMesh::operator=(*this);
6781 ret->setMesh(clmesh);
6782 ret->setAxisType(AX_CART);
6787 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6789 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6790 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6791 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6792 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6793 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6794 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6795 int spaceDim(_cmesh->getSpaceDimension());
6796 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6797 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6798 for(int i=0;i<spaceDim;i++)
6800 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6802 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6803 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
6804 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
6806 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6808 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6809 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6810 for(int i=0;i<spaceDim;i++)
6812 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6813 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6816 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6817 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6820 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6822 const MEDCouplingCMesh *cmesh=_cmesh;
6825 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6826 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6827 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6828 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6831 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6833 return new MEDFileCurveLinearMesh;
6836 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6838 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6841 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6843 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6844 return New(fid,mrs);
6847 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6849 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6850 return New(fid,mName,dt,it,mrs);
6853 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6855 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6858 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6860 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6863 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6865 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6866 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6870 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6872 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6876 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6878 return new MEDFileCurveLinearMesh;
6881 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6883 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6884 ret->deepCpyEquivalences(*this);
6885 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6886 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6887 ret->deepCpyAttributes();
6891 int MEDFileCurveLinearMesh::getMeshDimension() const
6893 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6894 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6895 return _clmesh->getMeshDimension();
6898 std::string MEDFileCurveLinearMesh::simpleRepr() const
6900 return MEDFileStructuredMesh::simpleRepr();
6903 std::string MEDFileCurveLinearMesh::advancedRepr() const
6905 return simpleRepr();
6908 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6910 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6912 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6915 what="Mesh types differ ! This is curve linear and other is NOT !";
6918 clearNonDiscrAttributes();
6919 otherC->clearNonDiscrAttributes();
6920 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6921 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6922 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6924 what="Mismatch of curve linear meshes ! One is defined and not other !";
6929 bool ret=coo1->isEqual(coo2,eps);
6932 what="curve linear meshes differ !";
6939 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6941 MEDFileStructuredMesh::clearNonDiscrAttributes();
6942 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6945 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6947 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6950 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6951 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6952 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6953 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6956 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6958 synchronizeTinyInfoOnLeaves();
6962 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6964 dealWithTinyInfo(m);
6970 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6972 if(getAxisType()==AX_CART)
6975 return const_cast<MEDFileCurveLinearMesh *>(this);
6979 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6981 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6982 const DataArrayDouble *coords(mesh->getCoords());
6984 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6985 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6986 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6987 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6988 mesh2->setCoords(coordsCart);
6989 ret->setMesh(mesh2);
6990 ret->setAxisType(AX_CART);
6995 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6997 synchronizeTinyInfoOnLeaves();
7001 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7005 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7008 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7010 catch(INTERP_KERNEL::Exception& e)
7015 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7017 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7018 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7019 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7020 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7021 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7022 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7023 int spaceDim=_clmesh->getSpaceDimension();
7024 int meshDim=_clmesh->getMeshDimension();
7025 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7026 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7027 const DataArrayDouble *coords=_clmesh->getCoords();
7029 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7030 for(int i=0;i<spaceDim;i++)
7032 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7034 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7035 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
7036 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
7038 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7040 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7041 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7042 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
7043 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
7045 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
7047 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7048 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7051 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7053 MEDCoupling::MEDCouplingMeshType meshType;
7056 MEDCoupling::MEDCouplingAxisType axType;
7057 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7058 setAxisType(axType);
7059 if(meshType!=CURVE_LINEAR)
7061 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7062 throw INTERP_KERNEL::Exception(oss.str().c_str());
7064 MEDFileCLMeshL2 loaderl2;
7065 loaderl2.loadAll(fid,mid,mName,dt,it);
7066 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7069 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7072 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7074 return new MEDFileMeshMultiTS;
7077 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7079 return new MEDFileMeshMultiTS(fid);
7082 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7084 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7088 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7090 return new MEDFileMeshMultiTS(fid,mName);
7093 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7095 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7096 return New(fid,mName);
7099 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7101 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7102 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7104 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7105 if((const MEDFileMesh *)*it)
7106 meshOneTs[i]=(*it)->deepCopy();
7107 ret->_mesh_one_ts=meshOneTs;
7111 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7113 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7116 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7118 std::vector<const BigMemoryObject *> ret;
7119 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7120 ret.push_back((const MEDFileMesh *)*it);
7124 std::string MEDFileMeshMultiTS::getName() const
7126 if(_mesh_one_ts.empty())
7127 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7128 return _mesh_one_ts[0]->getName();
7131 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7133 std::string oldName(getName());
7134 std::vector< std::pair<std::string,std::string> > v(1);
7135 v[0].first=oldName; v[0].second=newMeshName;
7139 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7142 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7144 MEDFileMesh *cur(*it);
7146 ret=cur->changeNames(modifTab) || ret;
7151 void MEDFileMeshMultiTS::cartesianizeMe()
7153 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7155 MEDFileMesh *cur(*it);
7158 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7164 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7166 if(_mesh_one_ts.empty())
7167 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7168 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7171 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7174 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7175 _mesh_one_ts.resize(1);
7176 mesh1TimeStep->incrRef();
7177 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7178 _mesh_one_ts[0]=mesh1TimeStep;
7181 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7183 if ( MEDFileMesh* m = getOneTimeStep() )
7184 return m->getJoints();
7189 * \brief Set Joints that are common to all time-stamps
7191 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7193 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7195 (*it)->setJoints( joints );
7199 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7201 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7202 if((*it).isNotNull())
7203 if((*it)->presenceOfStructureElements())
7208 void MEDFileMeshMultiTS::killStructureElements()
7210 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7211 if((*it).isNotNull())
7212 (*it)->killStructureElements();
7215 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7217 MEDFileJoints *joints(getJoints());
7218 bool jointsWritten(false);
7220 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7222 if ( jointsWritten )
7223 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7225 jointsWritten = true;
7227 (*it)->copyOptionsFrom(*this);
7228 (*it)->writeLL(fid);
7231 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7234 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7236 MEDFileJoints *joints(0);
7237 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7239 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7240 joints = getOneTimeStep()->getJoints();
7242 _mesh_one_ts.clear(); //for the moment to be improved
7243 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7246 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7250 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7253 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7256 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7257 throw INTERP_KERNEL::Exception(oss.str().c_str());
7260 MEDCoupling::MEDCouplingMeshType meshType;
7262 MEDCoupling::MEDCouplingAxisType dummy3;
7263 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7264 loadFromFile(fid,ms.front());
7266 catch(INTERP_KERNEL::Exception& e)
7271 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7274 loadFromFile(fid,mName);
7276 catch(INTERP_KERNEL::Exception& e)
7281 MEDFileMeshes *MEDFileMeshes::New()
7283 return new MEDFileMeshes;
7286 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7288 return new MEDFileMeshes(fid);
7291 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7293 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7297 void MEDFileMeshes::writeLL(med_idt fid) const
7299 checkConsistencyLight();
7300 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7302 (*it)->copyOptionsFrom(*this);
7303 (*it)->writeLL(fid);
7307 // MEDFileMeshes::writ checkConsistencyLight();
7309 int MEDFileMeshes::getNumberOfMeshes() const
7311 return _meshes.size();
7314 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7316 return new MEDFileMeshesIterator(this);
7319 /** Return a borrowed reference (caller is not responsible) */
7320 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7322 if(i<0 || i>=(int)_meshes.size())
7324 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7325 throw INTERP_KERNEL::Exception(oss.str().c_str());
7327 return _meshes[i]->getOneTimeStep();
7330 /** Return a borrowed reference (caller is not responsible) */
7331 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7333 std::vector<std::string> ms=getMeshesNames();
7334 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7337 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7338 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7339 throw INTERP_KERNEL::Exception(oss.str().c_str());
7341 return getMeshAtPos((int)std::distance(ms.begin(),it));
7344 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7346 std::vector<std::string> ret(_meshes.size());
7348 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7350 const MEDFileMeshMultiTS *f=(*it);
7353 ret[i]=f->getName();
7357 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7358 throw INTERP_KERNEL::Exception(oss.str().c_str());
7364 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7367 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7369 MEDFileMeshMultiTS *cur(*it);
7371 ret=cur->changeNames(modifTab) || ret;
7376 void MEDFileMeshes::cartesianizeMe()
7378 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7380 MEDFileMeshMultiTS *cur(*it);
7382 cur->cartesianizeMe();
7386 void MEDFileMeshes::resize(int newSize)
7388 _meshes.resize(newSize);
7391 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7394 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7395 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7396 elt->setOneTimeStep(mesh);
7397 _meshes.push_back(elt);
7400 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7403 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7404 if(i>=(int)_meshes.size())
7405 _meshes.resize(i+1);
7406 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7407 elt->setOneTimeStep(mesh);
7411 void MEDFileMeshes::destroyMeshAtPos(int i)
7413 if(i<0 || i>=(int)_meshes.size())
7415 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7416 throw INTERP_KERNEL::Exception(oss.str().c_str());
7418 _meshes.erase(_meshes.begin()+i);
7421 void MEDFileMeshes::loadFromFile(med_idt fid)
7423 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7425 _meshes.resize(ms.size());
7426 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7427 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7430 MEDFileMeshes::MEDFileMeshes()
7434 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7439 catch(INTERP_KERNEL::Exception& /*e*/)
7443 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7445 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7447 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7448 if((const MEDFileMeshMultiTS *)*it)
7449 meshes[i]=(*it)->deepCopy();
7450 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7451 ret->_meshes=meshes;
7455 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7457 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7460 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7462 std::vector<const BigMemoryObject *> ret;
7463 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7464 ret.push_back((const MEDFileMeshMultiTS *)*it);
7468 std::string MEDFileMeshes::simpleRepr() const
7470 std::ostringstream oss;
7471 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7472 simpleReprWithoutHeader(oss);
7476 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7478 int nbOfMeshes=getNumberOfMeshes();
7479 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7480 std::vector<std::string> mns=getMeshesNames();
7481 for(int i=0;i<nbOfMeshes;i++)
7482 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7485 void MEDFileMeshes::checkConsistencyLight() const
7487 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7489 std::set<std::string> s;
7490 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7492 const MEDFileMeshMultiTS *elt=(*it);
7495 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7496 throw INTERP_KERNEL::Exception(oss.str().c_str());
7498 std::size_t sz=s.size();
7499 s.insert(std::string((*it)->getName()));
7502 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7503 throw INTERP_KERNEL::Exception(oss.str().c_str());
7508 bool MEDFileMeshes::presenceOfStructureElements() const
7510 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7511 if((*it).isNotNull())
7512 if((*it)->presenceOfStructureElements())
7517 void MEDFileMeshes::killStructureElements()
7519 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7520 if((*it).isNotNull())
7521 (*it)->killStructureElements();
7524 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7529 _nb_iter=ms->getNumberOfMeshes();
7533 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7537 MEDFileMesh *MEDFileMeshesIterator::nextt()
7539 if(_iter_id<_nb_iter)
7541 MEDFileMeshes *ms(_ms);
7543 return ms->getMeshAtPos(_iter_id++);
7551 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7553 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7554 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7556 if(geoType==MED_NO_GEOTYPE)
7557 return INTERP_KERNEL::NORM_ERROR;
7558 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7559 throw INTERP_KERNEL::Exception(oss.str());
7561 return typmai2[std::distance(typmai,pos)];
7564 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7574 std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7575 throw INTERP_KERNEL::Exception(oss.str());