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 * This method also raises an exception if a family belonging to a group has also id 0 (which is not right in MED file format). You should never encounter this case using addGroup method.
832 * \sa MEDFileMesh::removeOrphanFamilies
834 void MEDFileMesh::rearrangeFamilies()
836 checkOrphanFamilyZero();
837 removeFamiliesReferedByNoGroups();
839 std::vector<int> levels(getNonEmptyLevelsExt());
840 std::set<int> idsRefed;
841 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
843 idsRefed.insert((*it).second);
846 if(!getGroupsOnFamily((*it).first).empty())
848 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Not orphan family \"" << (*it).first << "\" has id 0 ! This method may alterate groups in this for such a case !";
849 throw INTERP_KERNEL::Exception(oss.str());
853 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
855 const DataArrayInt *fams(0);
858 fams=getFamilyFieldAtLevel(*it);
860 catch(INTERP_KERNEL::Exception& e) { }
863 std::vector<bool> v(fams->getNumberOfTuples(),false);
864 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
865 fams->switchOnTupleEqualTo(*pt,v);
866 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
867 if(!unfetchedIds->empty())
869 MCAuto<DataArrayInt> newFams(fams->deepCopy());
870 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
871 setFamilyFieldArr(*it,newFams);
874 removeOrphanFamilies();
878 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
880 void MEDFileMesh::checkOrphanFamilyZero() const
882 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
884 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
886 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
887 throw INTERP_KERNEL::Exception(oss.str().c_str());
893 * Renames a group in \a this mesh.
894 * \param [in] oldName - a current name of the group to rename.
895 * \param [in] newName - a new group name.
896 * \throw If no group named \a oldName exists in \a this mesh.
897 * \throw If a group named \a newName already exists.
899 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
901 std::string oname(oldName);
902 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
903 std::vector<std::string> grps=getGroupsNames();
904 if(it==_groups.end())
906 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
907 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
908 throw INTERP_KERNEL::Exception(oss.str().c_str());
910 std::string nname(newName);
911 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
912 if(it2!=_groups.end())
914 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
915 throw INTERP_KERNEL::Exception(oss.str().c_str());
917 std::vector<std::string> cpy=(*it).second;
919 _groups[newName]=cpy;
923 * Changes an id of a family in \a this mesh.
924 * This method calls changeFamilyIdArr().
925 * \param [in] oldId - a current id of the family.
926 * \param [in] newId - a new family id.
928 void MEDFileMesh::changeFamilyId(int oldId, int newId)
930 changeFamilyIdArr(oldId,newId);
931 std::map<std::string,int> fam2;
932 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
934 if((*it).second==oldId)
935 fam2[(*it).first]=newId;
937 fam2[(*it).first]=(*it).second;
943 * Renames a family in \a this mesh.
944 * \param [in] oldName - a current name of the family to rename.
945 * \param [in] newName - a new family name.
946 * \throw If no family named \a oldName exists in \a this mesh.
947 * \throw If a family named \a newName already exists.
949 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
951 std::string oname(oldName);
952 std::map<std::string, int >::iterator it=_families.find(oname);
953 std::vector<std::string> fams=getFamiliesNames();
954 if(it==_families.end())
956 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
957 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
958 throw INTERP_KERNEL::Exception(oss.str().c_str());
960 std::string nname(newName);
961 std::map<std::string, int >::iterator it2=_families.find(nname);
962 if(it2!=_families.end())
964 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
965 throw INTERP_KERNEL::Exception(oss.str().c_str());
967 int cpy=(*it).second;
969 _families[newName]=cpy;
970 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
972 std::vector<std::string>& v=(*it3).second;
973 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
980 * Checks if \a this and another mesh contains the same families.
981 * \param [in] other - the mesh to compare with \a this one.
982 * \param [in,out] what - an unused parameter.
983 * \return bool - \c true if number of families and their ids are the same in the two
984 * meshes. Families with the id == \c 0 are not considered.
986 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
988 if(_families==other->_families)
990 std::map<std::string,int> fam0;
991 std::map<std::string,int> fam1;
992 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
994 fam0[(*it).first]=(*it).second;
995 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
997 fam1[(*it).first]=(*it).second;
1002 * Checks if \a this and another mesh contains the same groups.
1003 * \param [in] other - the mesh to compare with \a this one.
1004 * \param [in,out] what - a string describing a difference of groups of the two meshes
1005 * in case if this method returns \c false.
1006 * \return bool - \c true if number of groups and families constituting them are the
1007 * same in the two meshes.
1009 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
1011 if(_groups==other->_groups)
1014 std::size_t sz=_groups.size();
1015 if(sz!=other->_groups.size())
1017 what="Groups differ because not same number !\n";
1022 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
1023 for(std::size_t i=0;i<sz && ret;i++,it1++)
1025 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
1026 if(it2!=other->_groups.end())
1028 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
1029 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1035 what="A group in first mesh exists not in other !\n";
1041 std::ostringstream oss; oss << "Groups description differs :\n";
1042 oss << "First group description :\n";
1043 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1045 oss << " Group \"" << (*it).first << "\" on following families :\n";
1046 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1047 oss << " \"" << *it2 << "\n";
1049 oss << "Second group description :\n";
1050 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1052 oss << " Group \"" << (*it).first << "\" on following families :\n";
1053 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1054 oss << " \"" << *it2 << "\n";
1062 * Checks if a group with a given name exists in \a this mesh.
1063 * \param [in] groupName - the group name.
1064 * \return bool - \c true the group \a groupName exists in \a this mesh.
1066 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1068 std::string grpName(groupName);
1069 return _groups.find(grpName)!=_groups.end();
1073 * Checks if a family with a given id exists in \a this mesh.
1074 * \param [in] famId - the family id.
1075 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1077 bool MEDFileMesh::existsFamily(int famId) const
1079 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1080 if((*it2).second==famId)
1086 * Checks if a family with a given name exists in \a this mesh.
1087 * \param [in] familyName - the family name.
1088 * \return bool - \c true the family \a familyName exists in \a this mesh.
1090 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1092 std::string fname(familyName);
1093 return _families.find(fname)!=_families.end();
1097 * Sets an id of a family.
1098 * \param [in] familyName - the family name.
1099 * \param [in] id - a new id of the family.
1101 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1103 std::string fname(familyName);
1104 _families[fname]=id;
1107 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1109 std::string fname(familyName);
1110 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1111 if((*it).second==id)
1113 if((*it).first!=familyName)
1115 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1116 throw INTERP_KERNEL::Exception(oss.str().c_str());
1119 _families[fname]=id;
1123 * Adds a family to \a this mesh.
1124 * \param [in] familyName - a name of the family.
1125 * \param [in] famId - an id of the family.
1126 * \throw If a family with the same name or id already exists in \a this mesh.
1128 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1130 std::string fname(familyName);
1131 std::map<std::string,int>::const_iterator it=_families.find(fname);
1132 if(it==_families.end())
1134 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1135 if((*it2).second==famId)
1137 std::ostringstream oss;
1138 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1139 throw INTERP_KERNEL::Exception(oss.str().c_str());
1141 _families[fname]=famId;
1145 if((*it).second!=famId)
1147 std::ostringstream oss;
1148 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1149 throw INTERP_KERNEL::Exception(oss.str().c_str());
1155 * Creates a group including all mesh entities of given dimension.
1156 * \warning This method does \b not guarantee that the created group includes mesh
1157 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1158 * present in family fields of different dimensions. To assure this, call
1159 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1160 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1162 * \param [in] groupName - a name of the new group.
1163 * \throw If a group named \a groupName already exists.
1164 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1165 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1167 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1169 std::string grpName(groupName);
1170 std::vector<int> levs=getNonEmptyLevelsExt();
1171 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1173 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1174 oss << "Available relative ext levels are : ";
1175 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1176 throw INTERP_KERNEL::Exception(oss.str().c_str());
1178 if(existsGroup(groupName))
1180 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1181 oss << "Already existing groups are : ";
1182 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1183 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1184 throw INTERP_KERNEL::Exception(oss.str().c_str());
1186 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1188 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1189 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1190 std::vector<std::string> familiesOnWholeGroup;
1191 for(const int *it=famIds->begin();it!=famIds->end();it++)
1194 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1196 _groups[grpName]=familiesOnWholeGroup;
1200 * Ensures that given family ids do not present in family fields of dimensions different
1201 * than given ones. If a family id is present in the family fields of dimensions different
1202 * than the given ones, a new family is created and the whole data is updated accordingly.
1203 * \param [in] famIds - a sequence of family ids to check.
1204 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1205 * famIds should exclusively belong.
1206 * \return bool - \c true if no modification is done in \a this mesh by this method.
1208 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1210 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1211 std::vector<int> levs=getNonEmptyLevelsExt();
1212 std::set<int> levs2(levs.begin(),levs.end());
1213 std::vector<int> levsToTest;
1214 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1215 std::set<int> famIds2(famIds.begin(),famIds.end());
1218 if(!_families.empty())
1219 maxFamId=getMaxFamilyId()+1;
1220 std::vector<std::string> allFams=getFamiliesNames();
1221 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1223 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1226 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1227 std::vector<int> tmp;
1228 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1229 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1232 std::string famName=getFamilyNameGivenId(*it2);
1233 std::ostringstream oss; oss << "Family_" << maxFamId;
1234 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1235 addFamilyOnAllGroupsHaving(famName,zeName);
1236 _families[zeName]=maxFamId;
1237 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1246 * Adds a family to a given group in \a this mesh. If the group with a given name does
1247 * not exist, it is created.
1248 * \param [in] grpName - the name of the group to add the family in.
1249 * \param [in] famName - the name of the family to add to the group named \a grpName.
1250 * \throw If \a grpName or \a famName is an empty string.
1251 * \throw If no family named \a famName is present in \a this mesh.
1253 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1255 std::string grpn(grpName);
1256 std::string famn(famName);
1257 if(grpn.empty() || famn.empty())
1258 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1259 std::vector<std::string> fams=getFamiliesNames();
1260 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1262 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1263 oss << "Create this family or choose an existing one ! Existing fams are : ";
1264 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1265 throw INTERP_KERNEL::Exception(oss.str().c_str());
1267 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1268 if(it==_groups.end())
1270 _groups[grpn].push_back(famn);
1274 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1275 if(it2==(*it).second.end())
1276 (*it).second.push_back(famn);
1281 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1282 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1283 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1285 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1287 std::string famNameCpp(famName);
1288 std::string otherCpp(otherFamName);
1289 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1291 std::vector<std::string>& v=(*it).second;
1292 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1294 v.push_back(otherCpp);
1299 void MEDFileMesh::checkNoGroupClash(const DataArrayInt *famArr, const std::string& grpName) const
1301 std::vector<std::string> grpsNames(getGroupsNames());
1302 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
1304 std::vector<int> famIds(getFamiliesIdsOnGroup(grpName));
1305 if(famArr->presenceOfValue(famIds))
1307 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
1308 throw INTERP_KERNEL::Exception(oss.str().c_str());
1313 * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
1314 * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed)
1316 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1319 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1320 std::string grpName(ids->getName());
1322 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1323 ids->checkStrictlyMonotonic(true);
1324 checkNoGroupClash(famArr,grpName);
1325 MCAuto<DataArrayInt> famArrTmp; famArrTmp.takeRef(famArr);
1326 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1327 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1328 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1329 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1330 std::vector<int> familyIds;
1331 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1332 int maxVal=getTheMaxAbsFamilyId()+1;
1333 std::map<std::string,int> families(_families);
1334 std::map<std::string, std::vector<std::string> > groups(_groups);
1335 std::vector<std::string> fams;
1336 bool created(false);
1337 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1339 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1340 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1341 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1342 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1345 bool isFamPresent=false;
1346 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1347 isFamPresent=(*itl)->presenceOfValue(*famId);
1348 if(!isFamPresent && *famId!=0)
1349 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1352 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1353 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1354 fams.push_back(locFamName);
1355 if(existsFamily(*famId))
1357 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1358 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1361 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1365 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1366 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1367 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1368 if(existsFamily(*famId))
1370 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1371 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1376 for(std::size_t i=0;i<familyIds.size();i++)
1378 DataArrayInt *da=idsPerfamiliyIds[i];
1379 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1382 std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
1383 if(itt!=groups.end())
1385 std::vector<std::string>& famsOnGrp((*itt).second);
1386 famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
1389 groups[grpName]=fams;
1393 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1395 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1398 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1400 std::string fam(familyNameToChange);
1401 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1403 std::vector<std::string>& fams((*it).second);
1404 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1408 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1414 * Returns a name of the family having a given id or, if no such a family exists, creates
1415 * a new uniquely named family and returns its name.
1416 * \param [in] id - the id of the family whose name is required.
1417 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1418 * \return std::string - the name of the existing or the created family.
1419 * \throw If it is not possible to create a unique family name.
1421 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1423 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1427 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1428 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1429 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1430 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1432 * This method will throws an exception if it is not possible to create a unique family name.
1434 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1436 std::vector<std::string> famAlreadyExisting(families.size());
1438 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1440 if((*it).second!=id)
1442 famAlreadyExisting[ii]=(*it).first;
1451 std::ostringstream oss; oss << "Family_" << id;
1452 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1458 * Sets names and ids of all families in \a this mesh.
1459 * \param [in] info - a map of a family name to a family id.
1461 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1467 * Sets names of all groups and families constituting them in \a this mesh.
1468 * \param [in] info - a map of a group name to a vector of names of families
1469 * constituting the group.
1471 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1477 * Returns an id of the family having a given name.
1478 * \param [in] name - the name of the family of interest.
1479 * \return int - the id of the family of interest.
1480 * \throw If no family with such a \a name exists.
1482 int MEDFileMesh::getFamilyId(const std::string& name) const
1484 std::map<std::string, int>::const_iterator it=_families.find(name);
1485 if(it==_families.end())
1487 std::vector<std::string> fams(getFamiliesNames());
1488 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1489 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1490 throw INTERP_KERNEL::Exception(oss.str().c_str());
1492 return (*it).second;
1496 * Returns ids of the families having given names.
1497 * \param [in] fams - a sequence of the names of families of interest.
1498 * \return std::vector<int> - a sequence of the ids of families of interest.
1499 * \throw If \a fams contains a name of an inexistent family.
1501 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1503 std::vector<int> ret(fams.size());
1505 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1507 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1508 if(it2==_families.end())
1510 std::vector<std::string> fams2=getFamiliesNames();
1511 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1512 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1513 throw INTERP_KERNEL::Exception(oss.str().c_str());
1515 ret[i]=(*it2).second;
1521 * Returns a maximal abs(id) of families in \a this mesh.
1522 * \return int - the maximal norm of family id.
1523 * \throw If there are no families in \a this mesh.
1525 int MEDFileMesh::getMaxAbsFamilyId() const
1527 if(_families.empty())
1528 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1529 int ret=-std::numeric_limits<int>::max();
1530 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1532 ret=std::max(std::abs((*it).second),ret);
1538 * Returns a maximal id of families in \a this mesh.
1539 * \return int - the maximal family id.
1540 * \throw If there are no families in \a this mesh.
1542 int MEDFileMesh::getMaxFamilyId() const
1544 if(_families.empty())
1545 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1546 int ret=-std::numeric_limits<int>::max();
1547 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1549 ret=std::max((*it).second,ret);
1555 * Returns a minimal id of families in \a this mesh.
1556 * \return int - the minimal family id.
1557 * \throw If there are no families in \a this mesh.
1559 int MEDFileMesh::getMinFamilyId() const
1561 if(_families.empty())
1562 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1563 int ret=std::numeric_limits<int>::max();
1564 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1566 ret=std::min((*it).second,ret);
1572 * Returns a maximal id of families in \a this mesh. Not only named families are
1573 * considered but all family fields as well.
1574 * \return int - the maximal family id.
1576 int MEDFileMesh::getTheMaxAbsFamilyId() const
1578 int m1=-std::numeric_limits<int>::max();
1579 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1580 m1=std::max(std::abs((*it).second),m1);
1581 int m2=getMaxAbsFamilyIdInArrays();
1582 return std::max(m1,m2);
1586 * Returns a maximal id of families in \a this mesh. Not only named families are
1587 * considered but all family fields as well.
1588 * \return int - the maximal family id.
1590 int MEDFileMesh::getTheMaxFamilyId() const
1592 int m1=-std::numeric_limits<int>::max();
1593 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1594 m1=std::max((*it).second,m1);
1595 int m2=getMaxFamilyIdInArrays();
1596 return std::max(m1,m2);
1600 * Returns a minimal id of families in \a this mesh. Not only named families are
1601 * considered but all family fields as well.
1602 * \return int - the minimal family id.
1604 int MEDFileMesh::getTheMinFamilyId() const
1606 int m1=std::numeric_limits<int>::max();
1607 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1608 m1=std::min((*it).second,m1);
1609 int m2=getMinFamilyIdInArrays();
1610 return std::min(m1,m2);
1614 * This method only considers the maps. The contain of family array is ignored here.
1616 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1618 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1620 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1622 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1623 v.insert((*it).second);
1624 ret->alloc((int)v.size(),1);
1625 std::copy(v.begin(),v.end(),ret->getPointer());
1630 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1632 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1634 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1636 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1637 MCAuto<DataArrayInt> ret;
1638 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1640 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1641 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1642 if((DataArrayInt *) ret)
1643 ret=dv->buildUnion(ret);
1651 * true is returned if no modification has been needed. false if family
1652 * renumbering has been needed.
1654 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1656 std::vector<int> levs=getNonEmptyLevelsExt();
1657 std::set<int> allFamIds;
1658 int maxId=getMaxFamilyId()+1;
1659 std::map<int,std::vector<int> > famIdsToRenum;
1660 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1662 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1665 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1667 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1669 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1671 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1674 if(famIdsToRenum.empty())
1676 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1677 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1679 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1680 int *famIdsToChange=fam->getPointer();
1681 std::map<int,int> ren;
1682 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1684 if(allIds->presenceOfValue(*it3))
1686 std::string famName=getFamilyNameGivenId(*it3);
1687 std::vector<std::string> grps=getGroupsOnFamily(famName);
1690 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1691 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1692 addFamilyOnGrp((*it4),newFam);
1695 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1696 for(const int *id=ids->begin();id!=ids->end();id++)
1697 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1703 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1704 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1705 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1706 * This method will throw an exception if a same family id is detected in different level.
1707 * \warning This policy is the opposite of those in MED file documentation ...
1709 void MEDFileMesh::normalizeFamIdsTrio()
1711 ensureDifferentFamIdsPerLevel();
1712 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1713 std::vector<int> levs=getNonEmptyLevelsExt();
1714 std::set<int> levsS(levs.begin(),levs.end());
1715 std::set<std::string> famsFetched;
1716 std::map<std::string,int> families;
1717 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1720 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1724 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1725 std::map<int,int> ren;
1726 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1728 int nbOfTuples=fam->getNumberOfTuples();
1729 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1730 for(int *w=start;w!=start+nbOfTuples;w++)
1732 for(const int *it=tmp->begin();it!=tmp->end();it++)
1734 if(allIds->presenceOfValue(*it))
1736 std::string famName=getFamilyNameGivenId(*it);
1737 families[famName]=ren[*it];
1738 famsFetched.insert(famName);
1743 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1746 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1750 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1751 std::map<int,int> ren;
1752 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1754 int nbOfTuples=fam->getNumberOfTuples();
1755 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1756 for(int *w=start;w!=start+nbOfTuples;w++)
1758 for(const int *it=tmp->begin();it!=tmp->end();it++)
1760 if(allIds->presenceOfValue(*it))
1762 std::string famName=getFamilyNameGivenId(*it);
1763 families[famName]=ren[*it];
1764 famsFetched.insert(famName);
1769 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1771 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1774 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1775 fam->fillWithZero();
1776 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1777 if(allIds->presenceOfValue(*it3))
1779 std::string famName=getFamilyNameGivenId(*it3);
1780 families[famName]=0;
1781 famsFetched.insert(famName);
1786 std::vector<std::string> allFams=getFamiliesNames();
1787 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1788 std::set<std::string> unFetchedIds;
1789 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1790 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1791 families[*it4]=_families[*it4];
1796 * This method normalizes fam id with the following policy.
1797 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1798 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1799 * This method will throw an exception if a same family id is detected in different level.
1801 void MEDFileMesh::normalizeFamIdsMEDFile()
1803 ensureDifferentFamIdsPerLevel();
1804 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1805 std::vector<int> levs=getNonEmptyLevelsExt();
1806 std::set<int> levsS(levs.begin(),levs.end());
1807 std::set<std::string> famsFetched;
1808 std::map<std::string,int> families;
1810 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1813 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1816 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1817 std::map<int,int> ren;
1818 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1820 int nbOfTuples=fam->getNumberOfTuples();
1821 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1822 for(int *w=start;w!=start+nbOfTuples;w++)
1824 for(const int *it=tmp->begin();it!=tmp->end();it++)
1826 if(allIds->presenceOfValue(*it))
1828 std::string famName=getFamilyNameGivenId(*it);
1829 families[famName]=ren[*it];
1830 famsFetched.insert(famName);
1836 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1838 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1841 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1842 std::map<int,int> ren;
1843 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1845 int nbOfTuples=fam->getNumberOfTuples();
1846 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1847 for(int *w=start;w!=start+nbOfTuples;w++)
1849 for(const int *it=tmp->begin();it!=tmp->end();it++)
1851 if(allIds->presenceOfValue(*it))
1853 std::string famName=getFamilyNameGivenId(*it);
1854 families[famName]=ren[*it];
1855 famsFetched.insert(famName);
1861 std::vector<std::string> allFams=getFamiliesNames();
1862 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1863 std::set<std::string> unFetchedIds;
1864 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1865 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1866 families[*it4]=_families[*it4];
1871 * Returns a name of the family by its id. If there are several families having the given
1872 * id, the name first in lexical order is returned.
1873 * \param [in] id - the id of the family whose name is required.
1874 * \return std::string - the name of the found family.
1875 * \throw If no family with the given \a id exists.
1877 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1879 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1880 if((*it).second==id)
1882 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1883 throw INTERP_KERNEL::Exception(oss.str().c_str());
1887 * Returns a string describing \a this mesh. This description includes the mesh name and
1888 * the mesh description string.
1889 * \return std::string - the mesh information string.
1891 std::string MEDFileMesh::simpleRepr() const
1893 std::ostringstream oss;
1894 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1895 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1896 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1901 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1902 * an empty one is created.
1904 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1906 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1909 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1910 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1911 arr->fillWithZero();
1912 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1913 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1917 * Returns ids of mesh entities contained in a given group of a given dimension.
1918 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1920 * \param [in] grp - the name of the group of interest.
1921 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1922 * returned instead of ids.
1923 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1924 * numbers, if available and required, of mesh entities of the group. The caller
1925 * is to delete this array using decrRef() as it is no more needed.
1926 * \throw If the name of a nonexistent group is specified.
1927 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1929 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1931 std::vector<std::string> tmp(1);
1933 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1939 * Returns ids of mesh entities contained in given groups of a given dimension.
1940 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1942 * \param [in] grps - the names of the groups of interest.
1943 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1944 * returned instead of ids.
1945 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1946 * numbers, if available and required, of mesh entities of the groups. The caller
1947 * is to delete this array using decrRef() as it is no more needed.
1948 * \throw If the name of a nonexistent group is present in \a grps.
1949 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1951 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1953 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1954 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1958 * Returns ids of mesh entities contained in a given family of a given dimension.
1959 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1961 * \param [in] fam - the name of the family of interest.
1962 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1963 * returned instead of ids.
1964 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1965 * numbers, if available and required, of mesh entities of the family. The caller
1966 * is to delete this array using decrRef() as it is no more needed.
1967 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1969 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1971 std::vector<std::string> tmp(1);
1973 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1979 * Returns ids of nodes contained in a given group.
1980 * \param [in] grp - the name of the group of interest.
1981 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1982 * returned instead of ids.
1983 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1984 * numbers, if available and required, of nodes of the group. The caller
1985 * is to delete this array using decrRef() as it is no more needed.
1986 * \throw If the name of a nonexistent group is specified.
1987 * \throw If the family field is missing for nodes.
1989 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1991 std::vector<std::string> tmp(1);
1993 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1999 * Returns ids of nodes contained in given groups.
2000 * \param [in] grps - the names of the groups of interest.
2001 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2002 * returned instead of ids.
2003 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2004 * numbers, if available and required, of nodes of the groups. The caller
2005 * is to delete this array using decrRef() as it is no more needed.
2006 * \throw If the name of a nonexistent group is present in \a grps.
2007 * \throw If the family field is missing for nodes.
2009 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
2011 return getGroupsArr(1,grps,renum);
2015 * Returns ids of nodes contained in a given group.
2016 * \param [in] grp - the name of the group of interest.
2017 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2018 * returned instead of ids.
2019 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2020 * numbers, if available and required, of nodes of the group. The caller
2021 * is to delete this array using decrRef() as it is no more needed.
2022 * \throw If the name of a nonexistent group is specified.
2023 * \throw If the family field is missing for nodes.
2025 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
2027 std::vector<std::string> tmp(1);
2029 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
2035 * Returns ids of nodes contained in given families.
2036 * \param [in] fams - the names of the families of interest.
2037 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2038 * returned instead of ids.
2039 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2040 * numbers, if available and required, of nodes of the families. The caller
2041 * is to delete this array using decrRef() as it is no more needed.
2042 * \throw If the family field is missing for nodes.
2044 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2046 return getFamiliesArr(1,fams,renum);
2050 * Adds groups of given dimension and creates corresponding families and family fields
2051 * given ids of mesh entities of each group.
2052 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2053 * \param [in] grps - a sequence of arrays of ids each describing a group.
2054 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2056 * \throw If names of some groups in \a grps are equal.
2057 * \throw If \a grps includes a group with an empty name.
2058 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2059 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2061 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2065 std::set<std::string> grpsName;
2066 std::vector<std::string> grpsName2(grps.size());
2069 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2071 grpsName.insert((*it)->getName());
2072 grpsName2[i]=(*it)->getName();
2074 if(grpsName.size()!=grps.size())
2075 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2076 if(grpsName.find(std::string(""))!=grpsName.end())
2077 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2078 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2079 MCAuto<DataArrayInt> fam;
2080 std::vector< std::vector<int> > fidsOfGroups;
2083 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2087 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2088 for(unsigned int ii=0;ii<grps.size();ii++)
2090 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2091 grps2[ii]->setName(grps[ii]->getName());
2093 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2094 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2097 if(!_families.empty())
2098 offset=getMaxAbsFamilyId()+1;
2099 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2100 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2101 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2102 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2106 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2107 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2108 * For the moment, the two last input parameters are not taken into account.
2110 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2112 std::map<int,std::string> famInv;
2113 for(const int *it=famIds->begin();it!=famIds->end();it++)
2115 std::ostringstream oss;
2116 oss << "Family_" << (*it);
2117 _families[oss.str()]=(*it);
2118 famInv[*it]=oss.str();
2121 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2123 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2125 _groups[grpNames[i]].push_back(famInv[*it2]);
2130 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2132 std::vector<int> levs(getNonEmptyLevels());
2133 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2134 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2136 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2137 ret.insert(ret.end(),elts.begin(),elts.end());
2143 * \sa getAllDistributionOfTypes
2145 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2147 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2148 return mLev->getDistributionOfTypes();
2151 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2153 loadLL(fid,mName,dt,it,mrs);
2154 loadJointsFromFile(fid);
2155 loadEquivalences(fid);
2158 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2160 famArr->applyLin(offset>0?1:-1,offset,0);
2161 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2164 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2165 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2170 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2171 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2172 * If this method fails to find such a name it will throw an exception.
2174 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2177 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2180 std::size_t len=nameTry.length();
2181 for(std::size_t ii=1;ii<len;ii++)
2183 std::string tmp=nameTry.substr(ii,len-ii);
2184 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2190 for(std::size_t i=1;i<30;i++)
2192 std::string tmp1(nameTry.at(0),i);
2194 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2200 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2202 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2204 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2207 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2209 std::size_t nbOfChunks=code.size()/3;
2210 if(code.size()%3!=0)
2211 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2213 for(std::size_t i=0;i<nbOfChunks;i++)
2222 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2223 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2224 * If _name is not empty and that 'm' has the same name nothing is done.
2225 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2227 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2230 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2235 std::string name(m->getName());
2240 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2241 oss << name << "' ! Names must match !";
2242 throw INTERP_KERNEL::Exception(oss.str().c_str());
2246 if(_desc_name.empty())
2247 _desc_name=m->getDescription();
2250 std::string name(m->getDescription());
2253 if(_desc_name!=name)
2255 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2256 oss << name << "' ! Names must match !";
2257 throw INTERP_KERNEL::Exception(oss.str().c_str());
2263 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2265 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2266 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2268 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2269 oss << " - Groups lying on this family : ";
2270 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2271 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2272 oss << std::endl << std::endl;
2277 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2278 * file. The mesh to load is specified by its name and numbers of a time step and an
2280 * \param [in] fileName - the name of MED file to read.
2281 * \param [in] mName - the name of the mesh to read.
2282 * \param [in] dt - the number of a time step.
2283 * \param [in] it - the number of an iteration.
2284 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2285 * mesh using decrRef() as it is no more needed.
2286 * \throw If the file is not readable.
2287 * \throw If there is no mesh with given attributes in the file.
2288 * \throw If the mesh in the file is not an unstructured one.
2290 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2292 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2293 return New(fid,mName,dt,it,mrs);
2296 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2298 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2302 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2303 * file. The first mesh in the file is loaded.
2304 * \param [in] fileName - the name of MED file to read.
2305 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2306 * mesh using decrRef() as it is no more needed.
2307 * \throw If the file is not readable.
2308 * \throw If there is no meshes in the file.
2309 * \throw If the mesh in the file is not an unstructured one.
2311 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2313 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2314 return New(fid,mrs);
2318 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2320 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2323 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2324 throw INTERP_KERNEL::Exception(oss.str().c_str());
2327 MEDCoupling::MEDCouplingMeshType meshType;
2329 MEDCoupling::MEDCouplingAxisType dummy3;
2330 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2331 return T::New(fid,ms.front(),dt,it,mrs);
2334 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2336 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2340 * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2341 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2343 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2346 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2347 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2348 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2349 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2351 m2D->setCoords(m3D->getCoords());
2352 ret->setMeshAtLevel(0,m3D);
2353 ret->setMeshAtLevel(-1,m2D);
2354 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2359 * Returns an empty instance of MEDFileUMesh.
2360 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2361 * mesh using decrRef() as it is no more needed.
2363 MEDFileUMesh *MEDFileUMesh::New()
2365 return new MEDFileUMesh;
2369 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2370 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2371 * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh.
2372 * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce
2373 * at most the memory consumtion.
2375 * \param [in] fileName - the name of the file.
2376 * \param [in] mName - the name of the mesh to be read.
2377 * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
2378 * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
2379 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2380 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2381 * \param [in] mrs - the request for what to be loaded.
2382 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2384 MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2386 MEDFileUtilities::CheckFileForRead(fileName);
2387 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2388 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2392 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2393 * This method is \b NOT wrapped into python.
2395 MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2397 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2398 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2402 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2404 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2405 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2409 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2411 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2412 ret.push_back((const DataArrayDouble*)_coords);
2413 ret.push_back((const DataArrayInt *)_fam_coords);
2414 ret.push_back((const DataArrayInt *)_num_coords);
2415 ret.push_back((const DataArrayInt *)_global_num_coords);
2416 ret.push_back((const DataArrayInt *)_rev_num_coords);
2417 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2418 ret.push_back((const PartDefinition *)_part_coords);
2419 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2420 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2421 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2422 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2426 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2428 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2432 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2434 return new MEDFileUMesh;
2437 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2439 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2440 ret->deepCpyEquivalences(*this);
2441 if(_coords.isNotNull())
2442 ret->_coords=_coords->deepCopy();
2443 if(_fam_coords.isNotNull())
2444 ret->_fam_coords=_fam_coords->deepCopy();
2445 if(_num_coords.isNotNull())
2446 ret->_num_coords=_num_coords->deepCopy();
2447 if(_global_num_coords.isNotNull())
2448 ret->_global_num_coords=_global_num_coords->deepCopy();
2449 if(_rev_num_coords.isNotNull())
2450 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2451 if(_name_coords.isNotNull())
2452 ret->_name_coords=_name_coords->deepCopy();
2454 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2456 if((const MEDFileUMeshSplitL1 *)(*it))
2457 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2459 if((const PartDefinition*)_part_coords)
2460 ret->_part_coords=_part_coords->deepCopy();
2465 * Checks if \a this and another mesh are equal.
2466 * \param [in] other - the mesh to compare with.
2467 * \param [in] eps - a precision used to compare real values.
2468 * \param [in,out] what - the string returning description of unequal data.
2469 * \return bool - \c true if the meshes are equal, \c false, else.
2471 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2473 if(!MEDFileMesh::isEqual(other,eps,what))
2475 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2478 what="Mesh types differ ! This is unstructured and other is NOT !";
2481 clearNonDiscrAttributes();
2482 otherC->clearNonDiscrAttributes();
2483 const DataArrayDouble *coo1=_coords;
2484 const DataArrayDouble *coo2=otherC->_coords;
2485 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2487 what="Mismatch of coordinates ! One is defined and not other !";
2492 bool ret=coo1->isEqual(*coo2,eps);
2495 what="Coords differ !";
2500 const DataArrayInt *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2501 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2503 what="Mismatch of families arr on nodes ! One is defined and not other !";
2508 bool ret=famc1->isEqual(*famc2);
2511 what="Families arr on node differ !";
2517 const DataArrayInt *numc1(_num_coords),*numc2(otherC->_num_coords);
2518 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2520 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2525 bool ret=numc1->isEqual(*numc2);
2528 what="Numbering arr on node differ !";
2534 const DataArrayInt *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2535 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2537 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2542 bool ret=gnumc1->isEqual(*gnumc2);
2545 what="Global numbering arr on node differ !";
2551 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2552 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2554 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2559 bool ret=namec1->isEqual(*namec2);
2562 what="Names arr on node differ !";
2567 if(_ms.size()!=otherC->_ms.size())
2569 what="Number of levels differs !";
2572 std::size_t sz=_ms.size();
2573 for(std::size_t i=0;i<sz;i++)
2575 const MEDFileUMeshSplitL1 *s1=_ms[i];
2576 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2577 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2579 what="Mismatch of presence of sub levels !";
2584 bool ret=s1->isEqual(s2,eps,what);
2589 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2592 if((!pd0 && pd1) || (pd0 && !pd1))
2594 what=std::string("node part def is defined only for one among this or other !");
2597 return pd0->isEqual(pd1,what);
2601 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2602 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2603 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2604 * \throw if internal family array is inconsistent
2605 * \sa checkSMESHConsistency()
2607 void MEDFileUMesh::checkConsistency() const
2609 if(!_coords || !_coords->isAllocated())
2612 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2614 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2615 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2616 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2620 int nbCoo = _coords->getNumberOfTuples();
2621 if (_fam_coords.isNotNull())
2622 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2623 if (_num_coords.isNotNull())
2625 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2627 int maxValue=_num_coords->getMaxValue(pos);
2628 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2629 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2631 if (_global_num_coords.isNotNull())
2633 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2635 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2636 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2637 if (_num_coords && !_num_coords->hasUniqueValues())
2638 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2640 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2641 // Now sub part check:
2642 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2643 it != _ms.end(); it++)
2644 (*it)->checkConsistency();
2649 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2650 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2651 * entities as it likes), or non overlapping between all sub-levels.
2652 * \throw if the condition above is not respected
2654 void MEDFileUMesh::checkSMESHConsistency() const
2657 // For all sub-levels, numbering is either always null or with void intersection:
2660 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2661 std::vector< const DataArrayInt * > v;
2662 bool voidOrNot = ((*it)->_num == 0);
2663 for (it++; it != _ms.end(); it++)
2664 if( ((*it)->_num == 0) != voidOrNot )
2665 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2666 else if (!voidOrNot)
2667 v.push_back((*it)->_num);
2670 // don't forget the 1st one:
2671 v.push_back(_ms[0]->_num);
2672 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2673 if (inter->getNumberOfTuples())
2674 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2680 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2681 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2683 void MEDFileUMesh::clearNodeAndCellNumbers()
2685 _num_coords.nullify();
2686 _rev_num_coords.nullify();
2687 _global_num_coords.nullify();
2688 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2690 (*it)->_num.nullify();
2691 (*it)->_rev_num.nullify();
2692 (*it)->_global_num.nullify();
2697 * Clears redundant attributes of incorporated data arrays.
2699 void MEDFileUMesh::clearNonDiscrAttributes() const
2701 MEDFileMesh::clearNonDiscrAttributes();
2702 if(_coords.isNotNull())
2703 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2704 if(_fam_coords.isNotNull())
2705 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2706 if(_num_coords.isNotNull())
2707 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2708 if(_name_coords.isNotNull())
2709 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2710 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2712 if((*it).isNotNull())
2713 (*it)->clearNonDiscrAttributes();
2717 void MEDFileUMesh::setName(const std::string& name)
2719 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2720 if((*it).isNotNull())
2721 (*it)->setName(name);
2722 MEDFileMesh::setName(name);
2725 MEDFileUMesh::MEDFileUMesh()
2729 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2732 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2734 catch(INTERP_KERNEL::Exception& e)
2740 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2741 * See MEDFileUMesh::LoadPartOf for detailed description.
2745 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2747 MEDFileUMeshL2 loaderl2;
2748 MEDCoupling::MEDCouplingMeshType meshType;
2751 MEDCoupling::MEDCouplingAxisType dummy3;
2752 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2753 if(meshType!=UNSTRUCTURED)
2755 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2756 throw INTERP_KERNEL::Exception(oss.str().c_str());
2758 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2759 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2763 * \brief Write joints in a file
2765 void MEDFileMesh::writeJoints(med_idt fid) const
2767 if ( _joints.isNotNull() )
2768 _joints->writeLL(fid);
2772 * \brief Load joints in a file or use provided ones
2774 //================================================================================
2776 * \brief Load joints in a file or use provided ones
2777 * \param [in] fid - MED file descriptor
2778 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2779 * Usually this joints are those just read by another iteration
2780 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2782 //================================================================================
2784 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2786 if ( toUseInstedOfReading )
2787 setJoints( toUseInstedOfReading );
2789 _joints = MEDFileJoints::New( fid, _name );
2792 void MEDFileMesh::loadEquivalences(med_idt fid)
2794 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2796 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2799 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2801 const MEDFileEquivalences *equiv(other._equiv);
2803 _equiv=equiv->deepCopy(this);
2806 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2808 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2809 if(!thisEq && !otherEq)
2811 if(thisEq && otherEq)
2812 return thisEq->isEqual(otherEq,what);
2815 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2820 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2822 const MEDFileEquivalences *equiv(_equiv);
2825 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2826 _equiv->getRepr(oss);
2829 void MEDFileMesh::checkCartesian() const
2831 if(getAxisType()!=AX_CART)
2833 std::ostringstream oss; oss << "MEDFileMesh::checkCartesian : request for method that is dedicated to a cartesian convention ! But you are not in cartesian convention (" << DataArray::GetAxisTypeRepr(getAxisType()) << ").";
2834 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2835 oss << " - call setAxisType(AX_CART)" << std::endl;
2836 oss << " - call cartesianize()";
2837 throw INTERP_KERNEL::Exception(oss.str().c_str());
2842 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2844 int MEDFileMesh::getNumberOfJoints() const
2846 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2850 * \brief Return joints with all adjacent mesh domains
2852 MEDFileJoints * MEDFileMesh::getJoints() const
2854 return const_cast<MEDFileJoints*>(& (*_joints));
2857 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2859 if ( joints != _joints )
2868 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2870 * \sa loadPartUMeshFromFile
2872 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2874 MEDFileUMeshL2 loaderl2;
2875 MEDCoupling::MEDCouplingMeshType meshType;
2878 MEDCoupling::MEDCouplingAxisType axType;
2879 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2880 setAxisType(axType);
2881 if(meshType!=UNSTRUCTURED)
2883 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2884 throw INTERP_KERNEL::Exception(oss.str().c_str());
2886 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2887 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2888 // Structure element part...
2891 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2892 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2896 _elt_str.resize(nModels);
2897 for(int i=0;i<nModels;i++)
2898 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2901 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2903 int lev=loaderl2.getNumberOfLevels();
2905 for(int i=0;i<lev;i++)
2907 if(!loaderl2.emptyLev(i))
2908 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2912 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2914 setName(loaderl2.getName());
2915 setDescription(loaderl2.getDescription());
2916 setUnivName(loaderl2.getUnivName());
2917 setIteration(loaderl2.getIteration());
2918 setOrder(loaderl2.getOrder());
2919 setTimeValue(loaderl2.getTime());
2920 setTimeUnit(loaderl2.getTimeUnit());
2921 _coords=loaderl2.getCoords();
2922 if(!mrs || mrs->isNodeFamilyFieldReading())
2923 _fam_coords=loaderl2.getCoordsFamily();
2924 if(!mrs || mrs->isNodeNumFieldReading())
2925 _num_coords=loaderl2.getCoordsNum();
2926 if(!mrs || mrs->isNodeNameFieldReading())
2927 _name_coords=loaderl2.getCoordsName();
2928 if(!mrs || mrs->isGlobalNodeNumFieldReading())
2929 _global_num_coords=loaderl2.getCoordsGlobalNum();
2930 _part_coords=loaderl2.getPartDefOfCoo();
2934 MEDFileUMesh::~MEDFileUMesh()
2938 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2940 const DataArrayDouble *coo=_coords;
2941 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2942 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2943 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2944 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2945 int spaceDim=coo?coo->getNumberOfComponents():0;
2948 mdim=getMeshDimension();
2949 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2950 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2951 for(int i=0;i<spaceDim;i++)
2953 std::string info=coo->getInfoOnComponent(i);
2955 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2956 MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2957 MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
2959 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2961 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2962 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2963 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
2964 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2965 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2966 (*it)->write(fid,meshName,mdim);
2967 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2971 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2972 * \return std::vector<int> - a sequence of the relative dimensions.
2974 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2976 std::vector<int> ret;
2978 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2979 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2986 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2987 * \return std::vector<int> - a sequence of the relative dimensions.
2989 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2991 std::vector<int> ret0=getNonEmptyLevels();
2992 if((const DataArrayDouble *) _coords)
2994 std::vector<int> ret(ret0.size()+1);
2996 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3002 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
3004 std::vector<int> ret;
3005 const DataArrayInt *famCoo(_fam_coords);
3009 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3011 const MEDFileUMeshSplitL1 *cur(*it);
3013 if(cur->getFamilyField())
3019 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3021 std::vector<int> ret;
3022 if(_num_coords.isNotNull())
3025 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3027 const MEDFileUMeshSplitL1 *cur(*it);
3029 if(cur->getNumberField())
3035 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3037 std::vector<int> ret;
3038 const DataArrayAsciiChar *nameCoo(_name_coords);
3042 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3044 const MEDFileUMeshSplitL1 *cur(*it);
3046 if(cur->getNameField())
3053 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3054 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3055 * \param [in] fams - the name of the family of interest.
3056 * \return std::vector<int> - a sequence of the relative dimensions.
3058 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3060 std::vector<int> ret;
3061 std::vector<int> levs(getNonEmptyLevels());
3062 std::vector<int> famIds(getFamiliesIds(fams));
3063 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3064 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3070 * Returns all relative mesh levels (including nodes) where given families are defined.
3071 * \param [in] fams - the names of the families of interest.
3072 * \return std::vector<int> - a sequence of the relative dimensions.
3074 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3076 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
3077 const DataArrayInt *famCoords(_fam_coords);
3080 std::vector<int> famIds(getFamiliesIds(fams));
3081 if(famCoords->presenceOfValue(famIds))
3083 std::vector<int> ret(ret0.size()+1);
3085 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3092 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3094 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3095 if((const DataArrayInt *)_fam_coords)
3097 int val=_fam_coords->getMaxValue(tmp);
3098 ret=std::max(ret,std::abs(val));
3100 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3102 if((const MEDFileUMeshSplitL1 *)(*it))
3104 const DataArrayInt *da=(*it)->getFamilyField();
3107 int val=da->getMaxValue(tmp);
3108 ret=std::max(ret,std::abs(val));
3115 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3117 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3118 if((const DataArrayInt *)_fam_coords)
3120 int val=_fam_coords->getMaxValue(tmp);
3121 ret=std::max(ret,val);
3123 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3125 if((const MEDFileUMeshSplitL1 *)(*it))
3127 const DataArrayInt *da=(*it)->getFamilyField();
3130 int val=da->getMaxValue(tmp);
3131 ret=std::max(ret,val);
3138 int MEDFileUMesh::getMinFamilyIdInArrays() const
3140 int ret=std::numeric_limits<int>::max(),tmp=-1;
3141 if((const DataArrayInt *)_fam_coords)
3143 int val=_fam_coords->getMinValue(tmp);
3144 ret=std::min(ret,val);
3146 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3148 if((const MEDFileUMeshSplitL1 *)(*it))
3150 const DataArrayInt *da=(*it)->getFamilyField();
3153 int val=da->getMinValue(tmp);
3154 ret=std::min(ret,val);
3162 * Returns the dimension on cells in \a this mesh.
3163 * \return int - the mesh dimension.
3164 * \throw If there are no cells in this mesh.
3166 int MEDFileUMesh::getMeshDimension() const
3169 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3170 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3171 return (*it)->getMeshDimension()+lev;
3172 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3176 * Returns the space dimension of \a this mesh that is equal to number of components in
3177 * the node coordinates array.
3178 * \return int - the space dimension of \a this mesh.
3179 * \throw If the node coordinates array is not available.
3181 int MEDFileUMesh::getSpaceDimension() const
3183 const DataArrayDouble *coo=_coords;
3185 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3186 return coo->getNumberOfComponents();
3190 * Returns a string describing \a this mesh.
3191 * \return std::string - the mesh information string.
3193 std::string MEDFileUMesh::simpleRepr() const
3195 std::ostringstream oss;
3196 oss << MEDFileMesh::simpleRepr();
3197 const DataArrayDouble *coo=_coords;
3198 oss << "- The dimension of the space is ";
3199 static const char MSG1[]= "*** NO COORDS SET ***";
3200 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3202 oss << _coords->getNumberOfComponents() << std::endl;
3204 oss << MSG1 << std::endl;
3205 oss << "- Type of the mesh : UNSTRUCTURED\n";
3206 oss << "- Number of nodes : ";
3208 oss << _coords->getNumberOfTuples() << std::endl;
3210 oss << MSG1 << std::endl;
3211 std::size_t nbOfLev=_ms.size();
3212 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3213 for(std::size_t i=0;i<nbOfLev;i++)
3215 const MEDFileUMeshSplitL1 *lev=_ms[i];
3216 oss << " - Level #" << -((int) i) << " has dimension : ";
3219 oss << lev->getMeshDimension() << std::endl;
3220 lev->simpleRepr(oss);
3223 oss << MSG2 << std::endl;
3225 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3228 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3229 oss << "- Names of coordinates :" << std::endl;
3230 std::vector<std::string> vars=coo->getVarsOnComponent();
3231 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3232 oss << std::endl << "- Units of coordinates : " << std::endl;
3233 std::vector<std::string> units=coo->getUnitsOnComponent();
3234 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3236 oss << std::endl << std::endl;
3238 getEquivalencesRepr(oss);
3243 * Returns a full textual description of \a this mesh.
3244 * \return std::string - the string holding the mesh description.
3246 std::string MEDFileUMesh::advancedRepr() const
3248 return simpleRepr();
3252 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3253 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3254 * \return int - the number of entities.
3255 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3257 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3259 if(meshDimRelToMaxExt==1)
3261 if(!((const DataArrayDouble *)_coords))
3262 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3263 return _coords->getNumberOfTuples();
3265 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3269 * Returns the family field for mesh entities of a given dimension.
3270 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3271 * \return const DataArrayInt * - the family field. It is an array of ids of families
3272 * each mesh entity belongs to. It can be \c NULL.
3274 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3276 if(meshDimRelToMaxExt==1)
3278 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3279 return l1->getFamilyField();
3282 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3284 if(meshDimRelToMaxExt==1)
3286 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3287 return l1->getFamilyField();
3291 * Returns the optional numbers of mesh entities of a given dimension.
3292 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3293 * \return const DataArrayInt * - the array of the entity numbers.
3294 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3296 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3298 if(meshDimRelToMaxExt==1)
3300 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3301 return l1->getNumberField();
3304 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3306 if(meshDimRelToMaxExt==1)
3307 return _name_coords;
3308 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3309 return l1->getNameField();
3312 MCAuto<DataArrayInt> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3314 if(meshDimRelToMaxExt!=1)
3315 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3316 return _global_num_coords;
3320 * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file).
3322 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3323 * \param [in] gt - The input geometric type for which the part definition is requested.
3324 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3326 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3328 if(meshDimRelToMaxExt==1)
3329 return _part_coords;
3330 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3331 return l1->getPartDef(gt);
3334 int MEDFileUMesh::getNumberOfNodes() const
3336 const DataArrayDouble *coo(_coords);
3338 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3339 return coo->getNumberOfTuples();
3342 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3344 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3345 return l1->getNumberOfCells();
3348 bool MEDFileUMesh::hasImplicitPart() const
3353 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3355 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3358 void MEDFileUMesh::releaseImplicitPartIfAny() const
3362 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3364 std::size_t sz(st.getNumberOfItems());
3365 for(std::size_t i=0;i<sz;i++)
3367 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3368 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3369 if(st[i].getPflName().empty())
3370 m->computeNodeIdsAlg(nodesFetched);
3373 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3374 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3375 m2->computeNodeIdsAlg(nodesFetched);
3380 MEDFileMesh *MEDFileUMesh::cartesianize() const
3382 if(getAxisType()==AX_CART)
3385 return const_cast<MEDFileUMesh *>(this);
3389 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3390 const DataArrayDouble *coords(_coords);
3392 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3393 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3394 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3395 if((const MEDFileUMeshSplitL1 *)(*it))
3396 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3397 ret->_coords=coordsCart;
3398 ret->setAxisType(AX_CART);
3403 bool MEDFileUMesh::presenceOfStructureElements() const
3405 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3406 if((*it).isNotNull())
3411 void MEDFileUMesh::killStructureElements()
3417 * Returns the optional numbers of mesh entities of a given dimension transformed using
3418 * DataArrayInt::invertArrayN2O2O2N().
3419 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3420 * \return const DataArrayInt * - the array of the entity numbers transformed using
3421 * DataArrayInt::invertArrayN2O2O2N().
3422 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3424 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3426 if(meshDimRelToMaxExt==1)
3428 if(_num_coords.isNull())
3429 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3430 return _rev_num_coords;
3432 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3433 return l1->getRevNumberField();
3437 * Returns a pointer to the node coordinates array of \a this mesh \b without
3438 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3440 DataArrayDouble *MEDFileUMesh::getCoords() const
3443 MCAuto<DataArrayDouble> tmp(_coords);
3444 if((DataArrayDouble *)tmp)
3452 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3453 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3455 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3456 * \param [in] grp - the name of the group whose mesh entities are included in the
3458 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3459 * according to the optional numbers of entities, if available.
3460 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3461 * delete this mesh using decrRef() as it is no more needed.
3462 * \throw If the name of a nonexistent group is specified.
3463 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3465 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3468 synchronizeTinyInfoOnLeaves();
3469 std::vector<std::string> tmp(1);
3471 return getGroups(meshDimRelToMaxExt,tmp,renum);
3475 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3476 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3478 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3479 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3481 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3482 * according to the optional numbers of entities, if available.
3483 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3484 * delete this mesh using decrRef() as it is no more needed.
3485 * \throw If a name of a nonexistent group is present in \a grps.
3486 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3488 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3491 synchronizeTinyInfoOnLeaves();
3492 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3493 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3494 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3495 zeRet->setName(grps[0]);
3496 return zeRet.retn();
3500 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3501 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3503 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3504 * \param [in] fam - the name of the family whose mesh entities are included in the
3506 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3507 * according to the optional numbers of entities, if available.
3508 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3509 * delete this mesh using decrRef() as it is no more needed.
3510 * \throw If a name of a nonexistent family is present in \a grps.
3511 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3513 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3516 synchronizeTinyInfoOnLeaves();
3517 std::vector<std::string> tmp(1);
3519 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3523 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3524 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3526 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3527 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3529 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3530 * according to the optional numbers of entities, if available.
3531 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3532 * delete this mesh using decrRef() as it is no more needed.
3533 * \throw If a name of a nonexistent family is present in \a fams.
3534 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3536 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3539 synchronizeTinyInfoOnLeaves();
3540 if(meshDimRelToMaxExt==1)
3542 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3543 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3544 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3548 std::vector<int> famIds=getFamiliesIds(fams);
3549 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3550 MCAuto<MEDCouplingUMesh> zeRet;
3552 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3554 zeRet=l1->getFamilyPart(0,0,renum);
3555 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3556 zeRet->setName(fams[0]);
3557 return zeRet.retn();
3561 * Returns ids of mesh entities contained in given families of a given dimension.
3562 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3564 * \param [in] fams - the names of the families of interest.
3565 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3566 * returned instead of ids.
3567 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3568 * numbers, if available and required, of mesh entities of the families. The caller
3569 * is to delete this array using decrRef() as it is no more needed.
3570 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3572 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3574 std::vector<int> famIds=getFamiliesIds(fams);
3575 if(meshDimRelToMaxExt==1)
3577 if((const DataArrayInt *)_fam_coords)
3579 MCAuto<DataArrayInt> da;
3581 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3583 da=_fam_coords->findIdsEqualList(0,0);
3585 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3590 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3592 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3594 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3596 return l1->getFamilyPartArr(0,0,renum);
3600 * Returns a MEDCouplingUMesh of a given relative dimension.
3601 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3602 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3603 * To build a valid MEDCouplingUMesh from the returned one in this case,
3604 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3605 * \param [in] meshDimRelToMax - the relative dimension of interest.
3606 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3607 * optional numbers of mesh entities.
3608 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3609 * delete using decrRef() as it is no more needed.
3610 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3612 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3615 synchronizeTinyInfoOnLeaves();
3616 if(meshDimRelToMaxExt==1)
3620 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3621 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3622 umesh->setCoords(cc);
3623 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3624 umesh->setName(getName());
3628 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3629 return l1->getWholeMesh(renum);
3632 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3634 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3635 return l1->getDistributionOfTypes();
3639 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3640 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3641 * optional numbers of mesh entities.
3642 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3643 * delete using decrRef() as it is no more needed.
3644 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3646 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3648 return getMeshAtLevel(0,renum);
3652 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3653 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3654 * optional numbers of mesh entities.
3655 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3656 * delete using decrRef() as it is no more needed.
3657 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3659 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3661 return getMeshAtLevel(-1,renum);
3665 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3666 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3667 * optional numbers of mesh entities.
3668 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3669 * delete using decrRef() as it is no more needed.
3670 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3672 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3674 return getMeshAtLevel(-2,renum);
3678 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3679 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3680 * optional numbers of mesh entities.
3681 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3682 * delete using decrRef() as it is no more needed.
3683 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3685 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3687 return getMeshAtLevel(-3,renum);
3691 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3692 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3693 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3694 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3696 void MEDFileUMesh::forceComputationOfParts() const
3698 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3700 const MEDFileUMeshSplitL1 *elt(*it);
3702 elt->forceComputationOfParts();
3707 * This method returns a vector of mesh parts containing each exactly one geometric type.
3708 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3709 * This method is only for memory aware users.
3710 * The returned pointers are **NOT** new object pointer. No need to mange them.
3712 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3715 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3716 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3720 * This method returns the part of \a this having the geometric type \a gt.
3721 * If such part is not existing an exception will be thrown.
3722 * The returned pointer is **NOT** new object pointer. No need to mange it.
3724 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3727 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3728 int lev=(int)cm.getDimension()-getMeshDimension();
3729 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3730 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3734 * This method returns for each geo types in \a this number of cells with this geo type.
3735 * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated.
3736 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3738 * \sa getDistributionOfTypes
3740 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3742 std::vector< std::pair<int,int> > ret;
3743 std::vector<int> nel(getNonEmptyLevels());
3744 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3746 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3747 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3749 int nbCells(getNumberOfCellsWithType(*it1));
3750 ret.push_back(std::pair<int,int>(*it1,nbCells));
3753 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3758 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3759 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3761 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3763 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3764 return sp->getGeoTypes();
3767 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3769 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3770 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3771 return sp->getNumberOfCellsWithType(ct);
3775 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3776 * \param [in] gt - the geometric type for which the family field is asked.
3777 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3778 * delete using decrRef() as it is no more needed.
3779 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3781 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3783 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3784 int lev=(int)cm.getDimension()-getMeshDimension();
3785 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3786 return sp->extractFamilyFieldOnGeoType(gt);
3790 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3791 * \param [in] gt - the geometric type for which the number field is asked.
3792 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3793 * delete using decrRef() as it is no more needed.
3794 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3796 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3798 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3799 int lev=(int)cm.getDimension()-getMeshDimension();
3800 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3801 return sp->extractNumberFieldOnGeoType(gt);
3805 * This method returns for specified geometric type \a gt the relative level to \a this.
3806 * If the relative level is empty an exception will be thrown.
3808 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3810 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3811 int ret((int)cm.getDimension()-getMeshDimension());
3812 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3816 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3818 if(meshDimRelToMaxExt==1)
3819 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3820 if(meshDimRelToMaxExt>1)
3821 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3822 int tracucedRk=-meshDimRelToMaxExt;
3823 if(tracucedRk>=(int)_ms.size())
3824 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3825 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3826 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3827 return _ms[tracucedRk];
3830 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3832 if(meshDimRelToMaxExt==1)
3833 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3834 if(meshDimRelToMaxExt>1)
3835 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3836 int tracucedRk=-meshDimRelToMaxExt;
3837 if(tracucedRk>=(int)_ms.size())
3838 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3839 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3840 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3841 return _ms[tracucedRk];
3844 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3846 if(-meshDimRelToMax>=(int)_ms.size())
3847 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3849 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3851 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3853 int ref=(*it)->getMeshDimension();
3854 if(ref+i!=meshDim-meshDimRelToMax)
3855 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3861 * Sets the node coordinates array of \a this mesh.
3862 * \param [in] coords - the new node coordinates array.
3863 * \throw If \a coords == \c NULL.
3865 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3868 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3869 if(coords==(DataArrayDouble *)_coords)
3871 coords->checkAllocated();
3872 int nbOfTuples(coords->getNumberOfTuples());
3873 _coords.takeRef(coords);
3874 _fam_coords=DataArrayInt::New();
3875 _fam_coords->alloc(nbOfTuples,1);
3876 _fam_coords->fillWithZero();
3877 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3878 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3879 if((MEDFileUMeshSplitL1 *)(*it))
3880 (*it)->setCoords(coords);
3884 * Change coords without changing anything concerning families and numbering on nodes.
3886 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3889 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3890 if(coords==(DataArrayDouble *)_coords)
3892 coords->checkAllocated();
3893 int nbOfTuples(coords->getNumberOfTuples());
3894 if(_coords.isNull())
3901 int oldNbTuples(_coords->getNumberOfTuples());
3902 if(oldNbTuples!=nbOfTuples)
3903 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3907 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3908 if((MEDFileUMeshSplitL1 *)(*it))
3909 (*it)->setCoords(coords);
3913 * Removes all groups of a given dimension in \a this mesh.
3914 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3915 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3917 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3919 if(meshDimRelToMaxExt==1)
3921 if((DataArrayInt *)_fam_coords)
3922 _fam_coords->fillWithZero();
3925 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3926 l1->eraseFamilyField();
3931 * Removes all families with ids not present in the family fields of \a this mesh.
3933 void MEDFileUMesh::optimizeFamilies()
3935 std::vector<int> levs=getNonEmptyLevelsExt();
3936 std::set<int> allFamsIds;
3937 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3939 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3940 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3942 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3945 std::set<std::string> famNamesToKill;
3946 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3948 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3949 famNamesToKill.insert((*it).first);
3951 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3952 _families.erase(*it);
3953 std::vector<std::string> grpNamesToKill;
3954 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3956 std::vector<std::string> tmp;
3957 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3959 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3960 tmp.push_back(*it2);
3965 tmp.push_back((*it).first);
3967 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3972 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3973 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3974 * The boundary is built according to the following method:
3975 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3976 * coordinates array is extended).
3977 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3978 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3979 * might not be duplicated at all.
3980 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3981 * other side of the group is no more a neighbor)
3982 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3983 * bordering the newly created boundary use the newly computed nodes.
3984 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3985 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3987 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3988 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3990 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3991 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3992 * \sa clearNodeAndCellNumbers()
3994 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3995 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3997 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3998 typedef MCAuto<DataArrayInt> DAInt;
4000 std::vector<int> levs=getNonEmptyLevels();
4001 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
4002 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
4003 MUMesh m0=getMeshAtLevel(0);
4004 MUMesh m1=getMeshAtLevel(-1);
4005 int nbNodes=m0->getNumberOfNodes();
4006 MUMesh m11=getGroup(-1,grpNameM1);
4007 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
4008 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
4009 DAInt nodeIdsToDuplicate(tmp00);
4010 DAInt cellsToModifyConn0(tmp11);
4011 DAInt cellsToModifyConn1(tmp22);
4012 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4013 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4014 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
4015 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4016 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4017 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4018 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4019 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
4020 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4021 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4022 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4023 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4024 DAInt grpIds=getGroupArr(-1,grpNameM1);
4025 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4026 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4027 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4028 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4029 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4030 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4031 m0->setCoords(tmp0->getCoords());
4032 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4033 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4034 m1->setCoords(m0->getCoords());
4035 _coords=m0->getCoords(); _coords->incrRef();
4036 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4037 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4038 DataArrayInt * duplCells;
4039 m1->areCellsIncludedIn(m11, 0, duplCells);
4040 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4041 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4042 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4043 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4044 DAInt szOfCellGrpOfSameType(tmp00);
4045 DAInt idInMsOfCellGrpOfSameType(tmp11);
4047 newm1->setName(getName());
4048 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
4050 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4051 DAInt newFam=DataArrayInt::New();
4052 newFam->alloc(newm1->getNumberOfCells(),1);
4053 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4054 // Positive ID for family of nodes, negative for all the rest.
4056 if (m1->getMeshDimension() == 0)
4057 idd=getMaxFamilyId()+1;
4059 idd=getMinFamilyId()-1;
4060 int globStart=0,start=0,end,globEnd;
4061 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4062 for(int i=0;i<nbOfChunks;i++)
4064 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4065 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4067 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4068 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4069 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4074 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4078 newm1->setCoords(getCoords());
4079 setMeshAtLevel(-1,newm1);
4080 setFamilyFieldArr(-1,newFam);
4081 std::string grpName2(grpNameM1); grpName2+="_dup";
4082 addFamily(grpName2,idd);
4083 addFamilyOnGrp(grpName2,grpName2);
4088 int newNbOfNodes=getCoords()->getNumberOfTuples();
4089 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
4090 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4091 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4095 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4097 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4098 it != _ms.end(); it++)
4101 (*it)->_rev_num = 0;
4103 nodesDuplicated=nodeIdsToDuplicate.retn();
4104 cellsModified=cellsToModifyConn0.retn();
4105 cellsNotModified=cellsToModifyConn1.retn();
4108 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4109 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4112 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4113 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4114 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4116 * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering.
4117 * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered.
4119 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4121 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4122 std::vector<int> levs=getNonEmptyLevels();
4124 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4125 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4128 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4130 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4131 std::vector<int> code1=m->getDistributionOfTypes();
4132 end=PutInThirdComponentOfCodeOffset(code1,start);
4133 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4134 bool hasChanged=m->unPolyze();
4135 DataArrayInt *fake=0;
4136 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4137 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4139 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4142 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4143 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4145 MCAuto<DataArrayInt> famField2,numField2;
4146 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4147 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4148 setMeshAtLevel(*it,m);
4149 std::vector<int> code2=m->getDistributionOfTypes();
4150 end=PutInThirdComponentOfCodeOffset(code2,start);
4151 newCode.insert(newCode.end(),code2.begin(),code2.end());
4153 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4157 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4158 setFamilyFieldArr(*it,newFamField);
4162 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4163 setRenumFieldArr(*it,newNumField);
4168 newCode.insert(newCode.end(),code1.begin(),code1.end());
4174 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4175 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4176 o2nRenumCell=o2nRenumCellRet.retn();
4181 /*! \cond HIDDEN_ITEMS */
4182 struct MEDLoaderAccVisit1
4184 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4185 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4186 int _new_nb_of_nodes;
4191 * Array returned is the correspondence in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
4192 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4193 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4194 * -1 values in returned array means that the corresponding old node is no more used.
4196 * \return newly allocated array containing correspondence in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
4197 * is modified in \a this.
4198 * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
4201 DataArrayInt *MEDFileUMesh::zipCoords()
4203 const DataArrayDouble *coo(getCoords());
4205 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4206 int nbOfNodes(coo->getNumberOfTuples());
4207 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4208 std::vector<int> neLevs(getNonEmptyLevels());
4209 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4211 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4212 if(zeLev->isMeshStoredSplitByType())
4214 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4215 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4217 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4221 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4222 mesh->computeNodeIdsAlg(nodeIdsInUse);
4225 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4226 if(nbrOfNodesInUse==nbOfNodes)
4227 return 0;//no need to update _part_coords
4228 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4229 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4230 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4231 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4232 MCAuto<DataArrayInt> newFamCoords;
4233 MCAuto<DataArrayAsciiChar> newNameCoords;
4234 if((const DataArrayInt *)_fam_coords)
4235 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4236 MCAuto<DataArrayInt> newNumCoords,newGlobalNumCoords;
4237 if(_num_coords.isNotNull())
4238 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4239 if(_global_num_coords.isNotNull())
4240 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4241 if(_name_coords.isNotNull())
4242 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4243 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4244 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4246 if((MEDFileUMeshSplitL1*)*it)
4248 (*it)->renumberNodesInConn(ret->begin());
4249 (*it)->setCoords(_coords);
4252 // updates _part_coords
4253 const PartDefinition *pc(_part_coords);
4256 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4257 _part_coords=tmpPD->composeWith(pc);
4263 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4264 * The extraction of \a this is specified by the extractDef \a input map.
4265 * This map tells for each level of cells, the cells kept in the extraction.
4267 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4268 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4270 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4272 std::vector<int> levs(getNonEmptyLevels());
4273 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4274 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4277 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4278 if((*it).second.isNull())
4279 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4282 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4284 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4285 throw INTERP_KERNEL::Exception(oss.str());
4287 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4288 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4289 mPart->computeNodeIdsAlg(fetchedNodes);
4291 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4295 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4297 * \return - a new reference of MEDFileUMesh
4298 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4300 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4302 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4303 std::vector<int> levs(getNonEmptyLevels());
4304 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4307 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4308 if((*it).second.isNull())
4309 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4312 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4314 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4315 throw INTERP_KERNEL::Exception(oss.str());
4317 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4318 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4319 ret->setMeshAtLevel((*it).first,mPart);
4320 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4323 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4324 ret->setFamilyFieldArr((*it).first,famPart);
4328 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4329 ret->setFamilyFieldArr((*it).first,numPart);
4332 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4333 if(it2!=extractDef.end())
4335 const DataArrayDouble *coo(ret->getCoords());
4337 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4338 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4339 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4340 ret->setCoords(cooPart);
4341 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4344 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4345 ret->setFamilyFieldArr(1,famPart);
4349 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4350 ret->setFamilyFieldArr(1,numPart);
4352 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4356 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4357 m->renumberNodesInConn(o2nNodes->begin());
4358 ret->setMeshAtLevel((*it3).first,m);
4365 * This method performs an extrusion along a path defined by \a m1D.
4366 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4367 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4368 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4369 * This method scans all levels in \a this
4370 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4372 * \param [in] m1D - the mesh defining the extrusion path.
4373 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4374 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4376 * \sa MEDCouplingUMesh::buildExtrudedMesh
4378 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4381 if(getMeshDimension()!=2)
4382 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4383 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4384 m1D->checkConsistencyLight();
4385 if(m1D->getMeshDimension()!=1)
4386 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4387 int nbRep(m1D->getNumberOfCells());
4388 std::vector<int> levs(getNonEmptyLevels());
4389 std::vector<std::string> grps(getGroupsNames());
4390 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4391 DataArrayDouble *coords(0);
4392 std::size_t nbOfLevsOut(levs.size()+1);
4393 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4394 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4396 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4397 item=item->clone(false);
4398 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4399 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4400 tmp->changeSpaceDimension(3+(*lev),0.);
4401 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4402 zeList.push_back(elt);
4404 coords=elt->getCoords();
4407 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4408 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4410 (*it)->setName(getName());
4411 (*it)->setCoords(coords);
4413 for(std::size_t ii=0;ii!=zeList.size();ii++)
4416 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4419 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4420 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4421 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4422 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4423 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4424 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4425 std::vector<const MEDCouplingUMesh *> elts(3);
4426 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4427 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4428 elt->setName(getName());
4431 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4432 ret->setMeshAtLevel(lev,elt);
4434 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4435 endLev=endLev->clone(false); endLev->setCoords(coords);
4436 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4437 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4438 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4439 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4440 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4441 endLev->setName(getName());
4442 ret->setMeshAtLevel(levs.back()-1,endLev);
4444 for(std::size_t ii=0;ii!=zeList.size();ii++)
4447 std::vector< MCAuto<DataArrayInt> > outGrps;
4448 std::vector< const DataArrayInt * > outGrps2;
4451 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4453 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4454 if(!grpArr->empty())
4456 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4457 int offset0(zeList[ii]->getNumberOfCells());
4458 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4459 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4460 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4461 grpArr2->setName(oss.str());
4462 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4463 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4464 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4465 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4470 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4472 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4473 if(!grpArr->empty())
4475 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4476 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4477 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4478 for(int iii=0;iii<nbRep;iii++)
4480 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4481 grpArrs2[iii]=grpArrs[iii];
4483 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4484 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4485 std::ostringstream grpName; grpName << *grp << "_extruded";
4486 grpArrExt->setName(grpName.str());
4487 outGrps.push_back(grpArrExt);
4488 outGrps2.push_back(grpArrExt);
4491 ret->setGroupsAtLevel(lev,outGrps2);
4493 std::vector< MCAuto<DataArrayInt> > outGrps;
4494 std::vector< const DataArrayInt * > outGrps2;
4495 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4497 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4498 if(grpArr1->empty())
4500 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4501 std::ostringstream grpName; grpName << *grp << "_top";
4502 grpArr2->setName(grpName.str());
4503 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4504 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4505 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4507 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4512 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4513 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4514 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4516 * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple
4517 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4518 * \param [in] eps - detection threshold for coordinates.
4519 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4521 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4523 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4526 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4527 int initialNbNodes(getNumberOfNodes());
4528 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4529 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4531 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4533 DataArrayDouble *zeCoords(m0->getCoords());
4534 ret->setMeshAtLevel(0,m0);
4535 std::vector<int> levs(getNonEmptyLevels());
4536 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4539 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4540 ret->setFamilyFieldArr(0,famFieldCpy);
4542 famField=getFamilyFieldAtLevel(1);
4545 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4546 fam->fillWithZero();
4547 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4548 ret->setFamilyFieldArr(1,fam);
4550 ret->copyFamGrpMapsFrom(*this);
4551 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4552 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4556 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4557 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4558 if(m1->getMeshDimension()!=0)
4561 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4562 }//kill unused notUsed var
4563 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4565 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4566 MCAuto<DataArrayInt> bSafe(b);
4569 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4570 throw INTERP_KERNEL::Exception(oss.str().c_str());
4572 b->applyLin(1,initialNbNodes);
4573 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4574 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4575 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4576 m1->renumberNodesInConn(renum->begin());
4578 m1->setCoords(zeCoords);
4579 ret->setMeshAtLevel(*lev,m1);
4580 famField=getFamilyFieldAtLevel(*lev);
4583 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4584 ret->setFamilyFieldArr(*lev,famFieldCpy);
4591 * This method converts all quadratic cells in \a this into linear cells.
4592 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4593 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4595 * \param [in] eps - detection threshold for coordinates.
4596 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4598 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4600 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4603 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4604 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4605 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4606 m0->convertQuadraticCellsToLinear();
4608 DataArrayDouble *zeCoords(m0->getCoords());
4609 ret->setMeshAtLevel(0,m0);
4610 std::vector<int> levs(getNonEmptyLevels());
4611 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4614 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4615 ret->setFamilyFieldArr(0,famFieldCpy);
4617 famField=getFamilyFieldAtLevel(1);
4620 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4621 ret->setFamilyFieldArr(1,fam);
4623 ret->copyFamGrpMapsFrom(*this);
4624 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4628 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4629 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4630 m1->convertQuadraticCellsToLinear();
4633 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4634 MCAuto<DataArrayInt> bSafe(b);
4637 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4638 throw INTERP_KERNEL::Exception(oss.str().c_str());
4640 m1->renumberNodesInConn(b->begin());
4641 m1->setCoords(zeCoords);
4642 ret->setMeshAtLevel(*lev,m1);
4643 famField=getFamilyFieldAtLevel(*lev);
4646 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4647 ret->setFamilyFieldArr(*lev,famFieldCpy);
4654 * Computes the symmetry of \a this.
4655 * \return a new object.
4657 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4659 MCAuto<MEDFileUMesh> ret(deepCopy());
4660 DataArrayDouble *myCoo(getCoords());
4663 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4664 ret->setCoordsForced(newCoo);
4669 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4672 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4673 std::size_t sz(meshes.size()),i(0);
4674 std::vector<const DataArrayDouble *> coos(sz);
4675 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4676 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4679 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4680 coos[i]=(*it)->getCoords();
4681 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4682 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4684 const MEDFileUMesh *ref(meshes[0]);
4685 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4686 std::vector<int> levs(ref->getNonEmptyLevels());
4687 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4688 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4689 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4690 std::map<std::string,int> map1;
4691 std::map<std::string, std::vector<std::string> > map2;
4692 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4694 if((*it)->getSpaceDimension()!=spaceDim)
4695 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4696 if((*it)->getMeshDimension()!=meshDim)
4697 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4698 if((*it)->getNonEmptyLevels()!=levs)
4699 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4700 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4702 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4703 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4704 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4705 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4707 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4708 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4709 map1[(*it3).first]=(*it3).second;
4710 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4711 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4712 map2[(*it4).first]=(*it4).second;
4714 // Easy part : nodes
4715 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4716 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4717 ret->setCoords(coo);
4718 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4720 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4721 ret->setFamilyFieldArr(1,fam_coo);
4723 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4725 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4726 ret->setRenumFieldArr(1,num_coo);
4729 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4731 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4732 if(it2==m_mesh.end())
4733 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4734 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4735 mesh->setCoords(coo); mesh->setName(ref->getName());
4736 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4737 ret->setMeshAtLevel(*it,mesh);
4738 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4739 if(it3!=m_fam.end())
4741 const std::vector<const DataArrayInt *>& fams((*it3).second);
4742 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4744 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4745 famm->renumberInPlace(renum->begin());
4746 ret->setFamilyFieldArr(*it,famm);
4749 if(it4!=m_renum.end())
4751 const std::vector<const DataArrayInt *>& renums((*it4).second);
4752 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4754 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4755 renumm->renumberInPlace(renum->begin());
4756 ret->setRenumFieldArr(*it,renumm);
4761 ret->setFamilyInfo(map1);
4762 ret->setGroupInfo(map2);
4763 ret->setName(ref->getName());
4767 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4769 if(getMeshDimension()!=3)
4770 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4771 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4772 if(m3D.isNull() || m2D.isNull())
4773 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4774 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4775 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4779 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4781 clearNonDiscrAttributes();
4782 forceComputationOfParts();
4783 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4784 std::vector<int> layer0;
4785 layer0.push_back(getAxisType());//0 i
4786 layer0.push_back(_order); //1 i
4787 layer0.push_back(_iteration);//2 i
4788 layer0.push_back(getSpaceDimension());//3 i
4789 tinyDouble.push_back(_time);//0 d
4790 tinyStr.push_back(_name);//0 s
4791 tinyStr.push_back(_desc_name);//1 s
4792 for(int i=0;i<getSpaceDimension();i++)
4793 tinyStr.push_back(_coords->getInfoOnComponent(i));
4794 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4795 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4797 tinyStr.push_back((*it).first);
4798 layer0.push_back((*it).second);
4800 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4801 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4803 layer0.push_back((int)(*it0).second.size());
4804 tinyStr.push_back((*it0).first);
4805 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4806 tinyStr.push_back(*it1);
4808 // sizeof(layer0)==4+aa+1+bb layer#0
4809 bigArrayD=_coords;// 0 bd
4810 bigArraysI.push_back(_fam_coords);// 0 bi
4811 bigArraysI.push_back(_num_coords);// 1 bi
4812 const PartDefinition *pd(_part_coords);
4814 layer0.push_back(-1);
4817 std::vector<int> tmp0;
4818 pd->serialize(tmp0,bigArraysI);
4819 tinyInt.push_back(tmp0.size());
4820 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4823 std::vector<int> layer1;
4824 std::vector<int> levs(getNonEmptyLevels());
4825 layer1.push_back((int)levs.size());// 0 i <- key
4826 layer1.insert(layer1.end(),levs.begin(),levs.end());
4827 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4829 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4830 lev->serialize(layer1,bigArraysI);
4832 // put layers all together.
4833 tinyInt.push_back(layer0.size());
4834 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4835 tinyInt.push_back(layer1.size());
4836 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4839 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4840 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4842 int sz0(tinyInt[0]);
4843 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4844 int sz1(tinyInt[sz0+1]);
4845 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4847 std::reverse(layer0.begin(),layer0.end());
4848 std::reverse(layer1.begin(),layer1.end());
4849 std::reverse(tinyDouble.begin(),tinyDouble.end());
4850 std::reverse(tinyStr.begin(),tinyStr.end());
4851 std::reverse(bigArraysI.begin(),bigArraysI.end());
4853 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4854 _order=layer0.back(); layer0.pop_back();
4855 _iteration=layer0.back(); layer0.pop_back();
4856 int spaceDim(layer0.back()); layer0.pop_back();
4857 _time=tinyDouble.back(); tinyDouble.pop_back();
4858 _name=tinyStr.back(); tinyStr.pop_back();
4859 _desc_name=tinyStr.back(); tinyStr.pop_back();
4860 _coords=bigArrayD; _coords->rearrange(spaceDim);
4861 for(int i=0;i<spaceDim;i++)
4863 _coords->setInfoOnComponent(i,tinyStr.back());
4866 int nbOfFams(layer0.back()); layer0.pop_back();
4868 for(int i=0;i<nbOfFams;i++)
4870 _families[tinyStr.back()]=layer0.back();
4871 tinyStr.pop_back(); layer0.pop_back();
4873 int nbGroups(layer0.back()); layer0.pop_back();
4875 for(int i=0;i<nbGroups;i++)
4877 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4878 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4879 std::vector<std::string> fams(nbOfFamsOnGrp);
4880 for(int j=0;j<nbOfFamsOnGrp;j++)
4882 fams[j]=tinyStr.back(); tinyStr.pop_back();
4884 _groups[grpName]=fams;
4886 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4887 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4889 int isPd(layer0.back()); layer0.pop_back();
4892 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4893 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4894 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4897 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4899 int nbLevs(layer1.back()); layer1.pop_back();
4900 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4902 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4903 _ms.resize(maxLev+1);
4904 for(int i=0;i<nbLevs;i++)
4908 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4913 * Adds a group of nodes to \a this mesh.
4914 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4915 * The ids should be sorted and different each other (MED file norm).
4917 * \warning this method can alter default "FAMILLE_ZERO" family.
4918 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4920 * \throw If the node coordinates array is not set.
4921 * \throw If \a ids == \c NULL.
4922 * \throw If \a ids->getName() == "".
4923 * \throw If \a ids does not respect the MED file norm.
4924 * \throw If a group with name \a ids->getName() already exists.
4926 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4928 const DataArrayDouble *coords(_coords);
4930 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4931 int nbOfNodes(coords->getNumberOfTuples());
4932 if(_fam_coords.isNull())
4933 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4935 addGroupUnderground(true,ids,_fam_coords);
4939 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4941 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4942 * The ids should be sorted and different each other (MED file norm).
4944 * \warning this method can alter default "FAMILLE_ZERO" family.
4945 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4947 * \throw If the node coordinates array is not set.
4948 * \throw If \a ids == \c NULL.
4949 * \throw If \a ids->getName() == "".
4950 * \throw If \a ids does not respect the MED file norm.
4951 * \throw If a group with name \a ids->getName() already exists.
4953 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4955 std::vector<int> levs(getNonEmptyLevelsExt());
4956 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4958 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4959 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4961 if(meshDimRelToMaxExt==1)
4962 { addNodeGroup(ids); return ; }
4963 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4964 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4965 addGroupUnderground(false,ids,fam);
4969 * Changes a name of a family specified by its id.
4970 * \param [in] id - the id of the family of interest.
4971 * \param [in] newFamName - the new family name.
4972 * \throw If no family with the given \a id exists.
4974 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4976 std::string oldName=getFamilyNameGivenId(id);
4977 _families.erase(oldName);
4978 _families[newFamName]=id;
4982 * Removes a mesh of a given dimension.
4983 * \param [in] meshDimRelToMax - the relative dimension of interest.
4984 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4986 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4988 std::vector<int> levSet=getNonEmptyLevels();
4989 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4990 if(it==levSet.end())
4991 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4992 int pos=(-meshDimRelToMax);
4997 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4998 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4999 * \param [in] m - the new mesh to set.
5000 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5002 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5003 * another node coordinates array.
5004 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5005 * to the existing meshes of other levels of \a this mesh.
5007 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5009 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5010 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5014 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5015 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5016 * \param [in] m - the new mesh to set.
5017 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5018 * writing \a this mesh in a MED file.
5019 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5021 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5022 * another node coordinates array.
5023 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5024 * to the existing meshes of other levels of \a this mesh.
5026 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5028 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5029 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5032 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5034 dealWithTinyInfo(m);
5035 std::vector<int> levSet=getNonEmptyLevels();
5036 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5038 if((DataArrayDouble *)_coords==0)
5040 DataArrayDouble *c=m->getCoords();
5045 if(m->getCoords()!=_coords)
5046 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5047 int sz=(-meshDimRelToMax)+1;
5048 if(sz>=(int)_ms.size())
5050 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5054 return _ms[-meshDimRelToMax];
5058 * This method allows to set at once the content of different levels in \a this.
5059 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5061 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5062 * \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.
5063 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5065 * \throw If \a there is a null pointer in \a ms.
5066 * \sa MEDFileUMesh::setMeshAtLevel
5068 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5072 const MEDCouplingUMesh *mRef=ms[0];
5074 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5075 std::string name(mRef->getName());
5076 const DataArrayDouble *coo(mRef->getCoords());
5079 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5081 const MEDCouplingUMesh *cur(*it);
5083 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5084 if(coo!=cur->getCoords())
5085 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5086 int mdim=cur->getMeshDimension();
5087 zeDim=std::max(zeDim,mdim);
5088 if(s.find(mdim)!=s.end())
5089 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5091 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5093 int mdim=(*it)->getMeshDimension();
5094 setName((*it)->getName());
5095 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5101 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5102 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5103 * The given meshes must share the same node coordinates array.
5104 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5105 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5106 * create in \a this mesh.
5107 * \throw If \a ms is empty.
5108 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5109 * to the existing meshes of other levels of \a this mesh.
5110 * \throw If the meshes in \a ms do not share the same node coordinates array.
5111 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5112 * of the given meshes.
5113 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5114 * \throw If names of some meshes in \a ms are equal.
5115 * \throw If \a ms includes a mesh with an empty name.
5117 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5120 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5121 int sz=(-meshDimRelToMax)+1;
5122 if(sz>=(int)_ms.size())
5124 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5125 DataArrayDouble *coo=checkMultiMesh(ms);
5126 if((DataArrayDouble *)_coords==0)
5132 if((DataArrayDouble *)_coords!=coo)
5133 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5134 std::vector<DataArrayInt *> corr;
5135 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5136 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5137 setMeshAtLevel(meshDimRelToMax,m,renum);
5138 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5139 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5143 * Creates groups at a given level in \a this mesh from a sequence of
5144 * meshes each representing a group.
5145 * The given meshes must share the same node coordinates array.
5146 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5147 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5148 * create in \a this mesh.
5149 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5151 * \throw If \a ms is empty.
5152 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5153 * to the existing meshes of other levels of \a this mesh.
5154 * \throw If the meshes in \a ms do not share the same node coordinates array.
5155 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5156 * of the given meshes.
5157 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5158 * \throw If names of some meshes in \a ms are equal.
5159 * \throw If \a ms includes a mesh with an empty name.
5161 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5164 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5165 int sz=(-meshDimRelToMax)+1;
5166 if(sz>=(int)_ms.size())
5168 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5169 DataArrayDouble *coo=checkMultiMesh(ms);
5170 if((DataArrayDouble *)_coords==0)
5176 if((DataArrayDouble *)_coords!=coo)
5177 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5178 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5179 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5181 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5183 DataArrayInt *arr=0;
5184 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5188 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5189 throw INTERP_KERNEL::Exception(oss.str().c_str());
5192 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5193 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5196 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5198 const DataArrayDouble *ret=ms[0]->getCoords();
5199 int mdim=ms[0]->getMeshDimension();
5200 for(unsigned int i=1;i<ms.size();i++)
5202 ms[i]->checkConsistencyLight();
5203 if(ms[i]->getCoords()!=ret)
5204 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5205 if(ms[i]->getMeshDimension()!=mdim)
5206 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5208 return const_cast<DataArrayDouble *>(ret);
5212 * Sets the family field of a given relative dimension.
5213 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5214 * the family field is set.
5215 * \param [in] famArr - the array of the family field.
5216 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5217 * \throw If \a famArr has an invalid size.
5219 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5221 if(meshDimRelToMaxExt==1)
5228 DataArrayDouble *coo(_coords);
5230 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5231 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5232 _fam_coords.takeRef(famArr);
5235 if(meshDimRelToMaxExt>1)
5236 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5237 int traducedRk=-meshDimRelToMaxExt;
5238 if(traducedRk>=(int)_ms.size())
5239 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5240 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5241 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5242 return _ms[traducedRk]->setFamilyArr(famArr);
5246 * Sets the optional numbers of mesh entities of a given dimension.
5247 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5248 * \param [in] renumArr - the array of the numbers.
5249 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5250 * \throw If \a renumArr has an invalid size.
5252 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5254 if(meshDimRelToMaxExt==1)
5258 _num_coords.nullify();
5259 _rev_num_coords.nullify();
5262 if(_coords.isNull())
5263 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5264 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5265 _num_coords.takeRef(renumArr);
5269 if(meshDimRelToMaxExt>1)
5270 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5271 int traducedRk=-meshDimRelToMaxExt;
5272 if(traducedRk>=(int)_ms.size())
5273 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5274 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5275 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5276 return _ms[traducedRk]->setRenumArr(renumArr);
5280 * Sets the optional names of mesh entities of a given dimension.
5281 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5282 * \param [in] nameArr - the array of the names.
5283 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5284 * \throw If \a nameArr has an invalid size.
5286 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5288 if(meshDimRelToMaxExt==1)
5295 DataArrayDouble *coo(_coords);
5297 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5298 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5299 _name_coords.takeRef(nameArr);
5302 if(meshDimRelToMaxExt>1)
5303 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5304 int traducedRk=-meshDimRelToMaxExt;
5305 if(traducedRk>=(int)_ms.size())
5306 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5307 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5308 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5309 return _ms[traducedRk]->setNameArr(nameArr);
5312 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5314 if(meshDimRelToMaxExt!=1)
5315 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5317 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5318 _global_num_coords.takeRef(globalNumArr);
5321 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5323 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5324 if((const MEDFileUMeshSplitL1 *)(*it))
5325 (*it)->synchronizeTinyInfo(*this);
5329 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5331 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5333 DataArrayInt *arr=_fam_coords;
5335 arr->changeValue(oldId,newId);
5336 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5338 MEDFileUMeshSplitL1 *sp=(*it);
5341 sp->changeFamilyIdArr(oldId,newId);
5346 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5348 std::list< MCAuto<DataArrayInt> > ret;
5349 const DataArrayInt *da(_fam_coords);
5351 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5352 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5354 const MEDFileUMeshSplitL1 *elt(*it);
5357 da=elt->getFamilyField();
5359 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5365 void MEDFileUMesh::computeRevNum() const
5367 if(_num_coords.isNotNull())
5370 int maxValue=_num_coords->getMaxValue(pos);
5371 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5375 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5377 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5380 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5382 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5383 ret.push_back((const DataArrayInt *)_fam_nodes);
5384 ret.push_back((const DataArrayInt *)_num_nodes);
5385 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5386 ret.push_back((const DataArrayInt *)_fam_cells);
5387 ret.push_back((const DataArrayInt *)_num_cells);
5388 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5389 ret.push_back((const DataArrayInt *)_fam_faces);
5390 ret.push_back((const DataArrayInt *)_num_faces);
5391 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5392 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5393 ret.push_back((const DataArrayInt *)_rev_num_cells);
5394 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5398 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5400 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5401 if((const DataArrayInt *)_fam_nodes)
5403 int val=_fam_nodes->getMaxValue(tmp);
5404 ret=std::max(ret,std::abs(val));
5406 if((const DataArrayInt *)_fam_cells)
5408 int val=_fam_cells->getMaxValue(tmp);
5409 ret=std::max(ret,std::abs(val));
5411 if((const DataArrayInt *)_fam_faces)
5413 int val=_fam_faces->getMaxValue(tmp);
5414 ret=std::max(ret,std::abs(val));
5419 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5421 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5422 if((const DataArrayInt *)_fam_nodes)
5424 int val=_fam_nodes->getMaxValue(tmp);
5425 ret=std::max(ret,val);
5427 if((const DataArrayInt *)_fam_cells)
5429 int val=_fam_cells->getMaxValue(tmp);
5430 ret=std::max(ret,val);
5432 if((const DataArrayInt *)_fam_faces)
5434 int val=_fam_faces->getMaxValue(tmp);
5435 ret=std::max(ret,val);
5440 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5442 int ret=std::numeric_limits<int>::max(),tmp=-1;
5443 if((const DataArrayInt *)_fam_nodes)
5445 int val=_fam_nodes->getMinValue(tmp);
5446 ret=std::min(ret,val);
5448 if((const DataArrayInt *)_fam_cells)
5450 int val=_fam_cells->getMinValue(tmp);
5451 ret=std::min(ret,val);
5453 if((const DataArrayInt *)_fam_faces)
5455 int val=_fam_faces->getMinValue(tmp);
5456 ret=std::min(ret,val);
5461 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5463 if(!MEDFileMesh::isEqual(other,eps,what))
5465 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5468 what="Mesh types differ ! This is structured and other is NOT !";
5471 const DataArrayInt *famc1=_fam_nodes;
5472 const DataArrayInt *famc2=otherC->_fam_nodes;
5473 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5475 what="Mismatch of families arr on nodes ! One is defined and not other !";
5480 bool ret=famc1->isEqual(*famc2);
5483 what="Families arr on nodes differ !";
5488 famc2=otherC->_fam_cells;
5489 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5491 what="Mismatch of families arr on cells ! One is defined and not other !";
5496 bool ret=famc1->isEqual(*famc2);
5499 what="Families arr on cells differ !";
5504 famc2=otherC->_fam_faces;
5505 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5507 what="Mismatch of families arr on faces ! One is defined and not other !";
5512 bool ret=famc1->isEqual(*famc2);
5515 what="Families arr on faces differ !";
5520 famc2=otherC->_num_nodes;
5521 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5523 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5528 bool ret=famc1->isEqual(*famc2);
5531 what="Numbering arr on nodes differ !";
5536 famc2=otherC->_num_cells;
5537 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5539 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5544 bool ret=famc1->isEqual(*famc2);
5547 what="Numbering arr on cells differ !";
5552 famc2=otherC->_num_faces;
5553 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5555 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5560 bool ret=famc1->isEqual(*famc2);
5563 what="Numbering arr on faces differ !";
5567 const DataArrayAsciiChar *d1=_names_cells;
5568 const DataArrayAsciiChar *d2=otherC->_names_cells;
5569 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5571 what="Mismatch of naming arr on cells ! One is defined and not other !";
5576 bool ret=d1->isEqual(*d2);
5579 what="Naming arr on cells differ !";
5584 d2=otherC->_names_faces;
5585 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5587 what="Mismatch of naming arr on faces ! One is defined and not other !";
5592 bool ret=d1->isEqual(*d2);
5595 what="Naming arr on faces differ !";
5600 d2=otherC->_names_nodes;
5601 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5603 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5608 bool ret=d1->isEqual(*d2);
5611 what="Naming arr on nodes differ !";
5618 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5620 MEDFileMesh::clearNonDiscrAttributes();
5621 const DataArrayInt *tmp=_fam_nodes;
5623 (const_cast<DataArrayInt *>(tmp))->setName("");
5626 (const_cast<DataArrayInt *>(tmp))->setName("");
5629 (const_cast<DataArrayInt *>(tmp))->setName("");
5632 (const_cast<DataArrayInt *>(tmp))->setName("");
5635 (const_cast<DataArrayInt *>(tmp))->setName("");
5638 (const_cast<DataArrayInt *>(tmp))->setName("");
5642 * Returns ids of mesh entities contained in given families of a given dimension.
5643 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5645 * \param [in] fams - the names of the families of interest.
5646 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5647 * returned instead of ids.
5648 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5649 * numbers, if available and required, of mesh entities of the families. The caller
5650 * is to delete this array using decrRef() as it is no more needed.
5651 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5653 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5655 std::vector<int> famIds(getFamiliesIds(fams));
5656 switch(meshDimRelToMaxExt)
5660 if((const DataArrayInt *)_fam_nodes)
5662 MCAuto<DataArrayInt> da;
5664 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5666 da=_fam_nodes->findIdsEqualList(0,0);
5668 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5673 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5678 if((const DataArrayInt *)_fam_cells)
5680 MCAuto<DataArrayInt> da;
5682 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5684 da=_fam_cells->findIdsEqualList(0,0);
5686 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5691 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5696 if((const DataArrayInt *)_fam_faces)
5698 MCAuto<DataArrayInt> da;
5700 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5702 da=_fam_faces->findIdsEqualList(0,0);
5704 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5709 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5713 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5715 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5719 * Sets the family field of a given relative dimension.
5720 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5721 * the family field is set.
5722 * \param [in] famArr - the array of the family field.
5723 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5724 * \throw If \a famArr has an invalid size.
5725 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5727 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5729 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5731 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5732 switch(meshDimRelToMaxExt)
5736 int nbCells(mesh->getNumberOfCells());
5738 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5744 int nbNodes(mesh->getNumberOfNodes());
5746 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5752 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5754 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5759 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5766 * Sets the optional numbers of mesh entities of a given dimension.
5767 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5768 * \param [in] renumArr - the array of the numbers.
5769 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5770 * \throw If \a renumArr has an invalid size.
5771 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5773 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5775 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5777 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5778 switch(meshDimRelToMaxExt)
5782 int nbCells=mesh->getNumberOfCells();
5783 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5784 _num_cells=renumArr;
5789 int nbNodes=mesh->getNumberOfNodes();
5790 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5791 _num_nodes=renumArr;
5796 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5797 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5798 _num_faces=renumArr;
5802 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5805 renumArr->incrRef();
5809 * Sets the optional names of mesh entities of a given dimension.
5810 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5811 * \param [in] nameArr - the array of the names.
5812 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5813 * \throw If \a nameArr has an invalid size.
5815 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5817 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5819 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5820 switch(meshDimRelToMaxExt)
5824 int nbCells=mesh->getNumberOfCells();
5825 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5826 _names_cells=nameArr;
5831 int nbNodes=mesh->getNumberOfNodes();
5832 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5833 _names_nodes=nameArr;
5838 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5839 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5840 _names_cells=nameArr;
5843 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5849 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayInt *globalNumArr)
5851 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
5855 * Adds a group of nodes to \a this mesh.
5856 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5857 * The ids should be sorted and different each other (MED file norm).
5859 * \warning this method can alter default "FAMILLE_ZERO" family.
5860 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5862 * \throw If the node coordinates array is not set.
5863 * \throw If \a ids == \c NULL.
5864 * \throw If \a ids->getName() == "".
5865 * \throw If \a ids does not respect the MED file norm.
5866 * \throw If a group with name \a ids->getName() already exists.
5868 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5874 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5876 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5877 * The ids should be sorted and different each other (MED file norm).
5879 * \warning this method can alter default "FAMILLE_ZERO" family.
5880 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5882 * \throw If the node coordinates array is not set.
5883 * \throw If \a ids == \c NULL.
5884 * \throw If \a ids->getName() == "".
5885 * \throw If \a ids does not respect the MED file norm.
5886 * \throw If a group with name \a ids->getName() already exists.
5888 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5890 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5891 addGroupUnderground(false,ids,fam);
5896 * Returns the family field for mesh entities of a given dimension.
5897 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5898 * \return const DataArrayInt * - the family field. It is an array of ids of families
5899 * each mesh entity belongs to. It can be \c NULL.
5900 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5902 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5904 switch(meshDimRelToMaxExt)
5913 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5918 * Returns the family field for mesh entities of a given dimension.
5919 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5920 * \return const DataArrayInt * - the family field. It is an array of ids of families
5921 * each mesh entity belongs to. It can be \c NULL.
5922 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5924 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5926 switch(meshDimRelToMaxExt)
5935 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5940 * Returns the optional numbers of mesh entities of a given dimension.
5941 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5942 * \return const DataArrayInt * - the array of the entity numbers.
5943 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5944 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5946 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5948 switch(meshDimRelToMaxExt)
5957 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5962 * Returns the optional numbers of mesh entities of a given dimension transformed using
5963 * DataArrayInt::invertArrayN2O2O2N().
5964 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5965 * \return const DataArrayInt * - the array of the entity numbers transformed using
5966 * DataArrayInt::invertArrayN2O2O2N().
5967 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5968 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5970 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5972 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5973 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5974 if(meshDimRelToMaxExt==0)
5976 if((const DataArrayInt *)_num_cells)
5979 int maxValue=_num_cells->getMaxValue(pos);
5980 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5981 return _rev_num_cells;
5984 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5988 if((const DataArrayInt *)_num_nodes)
5991 int maxValue=_num_nodes->getMaxValue(pos);
5992 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5993 return _rev_num_nodes;
5996 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6000 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6002 switch(meshDimRelToMaxExt)
6005 return _names_cells;
6007 return _names_nodes;
6009 return _names_faces;
6011 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6015 MCAuto<DataArrayInt> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6017 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6021 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6022 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6024 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6026 std::vector<int> ret(1);
6031 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6032 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6034 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6036 std::vector<int> ret(2);
6042 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6044 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6046 std::vector<int> ret;
6047 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6058 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6060 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6062 std::vector<int> ret;
6063 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6074 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6076 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6078 std::vector<int> ret;
6079 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6090 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6092 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
6094 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6098 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
6100 DataArrayInt *arr=_fam_nodes;
6102 arr->changeValue(oldId,newId);
6105 arr->changeValue(oldId,newId);
6108 arr->changeValue(oldId,newId);
6111 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6113 std::list< MCAuto<DataArrayInt> > ret;
6114 const DataArrayInt *da(_fam_nodes);
6116 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6119 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6122 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6126 void MEDFileStructuredMesh::deepCpyAttributes()
6128 if((const DataArrayInt*)_fam_nodes)
6129 _fam_nodes=_fam_nodes->deepCopy();
6130 if((const DataArrayInt*)_num_nodes)
6131 _num_nodes=_num_nodes->deepCopy();
6132 if((const DataArrayAsciiChar*)_names_nodes)
6133 _names_nodes=_names_nodes->deepCopy();
6134 if((const DataArrayInt*)_fam_cells)
6135 _fam_cells=_fam_cells->deepCopy();
6136 if((const DataArrayInt*)_num_cells)
6137 _num_cells=_num_cells->deepCopy();
6138 if((const DataArrayAsciiChar*)_names_cells)
6139 _names_cells=_names_cells->deepCopy();
6140 if((const DataArrayInt*)_fam_faces)
6141 _fam_faces=_fam_faces->deepCopy();
6142 if((const DataArrayInt*)_num_faces)
6143 _num_faces=_num_faces->deepCopy();
6144 if((const DataArrayAsciiChar*)_names_faces)
6145 _names_faces=_names_faces->deepCopy();
6146 if((const DataArrayInt*)_rev_num_nodes)
6147 _rev_num_nodes=_rev_num_nodes->deepCopy();
6148 if((const DataArrayInt*)_rev_num_cells)
6149 _rev_num_cells=_rev_num_cells->deepCopy();
6153 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6155 * \return a pointer to cartesian mesh that need to be managed by the caller.
6156 * \warning the returned pointer has to be managed by the caller.
6160 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6161 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6162 * \param [in] renum - it must be \c false.
6163 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6164 * delete using decrRef() as it is no more needed.
6166 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6170 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6171 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6172 switch(meshDimRelToMax)
6178 return const_cast<MEDCouplingStructuredMesh *>(m);
6183 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6184 buildMinusOneImplicitPartIfNeeded();
6185 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6191 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6195 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6197 std::vector<int> ret;
6198 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6199 if(famCells && famCells->presenceOfValue(ret))
6201 if(famFaces && famFaces->presenceOfValue(ret))
6206 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6208 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6209 const DataArrayInt *famNodes(_fam_nodes);
6210 if(famNodes && famNodes->presenceOfValue(ret))
6216 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6217 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6218 * \return int - the number of entities.
6219 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6221 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6223 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6225 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6226 switch(meshDimRelToMaxExt)
6229 return cmesh->getNumberOfCells();
6231 return cmesh->getNumberOfNodes();
6233 return cmesh->getNumberOfCellsOfSubLevelMesh();
6235 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6239 int MEDFileStructuredMesh::getNumberOfNodes() const
6241 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6243 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6244 return cmesh->getNumberOfNodes();
6247 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6249 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6251 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6252 switch(meshDimRelToMaxExt)
6255 return cmesh->getNumberOfCells();
6257 return cmesh->getNumberOfCellsOfSubLevelMesh();
6259 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6263 bool MEDFileStructuredMesh::hasImplicitPart() const
6269 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6271 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6273 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6274 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6277 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6278 if(cm.getReverseExtrudedType()!=gt)
6279 throw INTERP_KERNEL::Exception(MSG);
6280 buildImplicitPart();
6281 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6285 if(gt!=zeFaceMesh->getCellModelEnum())
6286 throw INTERP_KERNEL::Exception(MSG);
6287 return zeFaceMesh->getNumberOfCells();
6291 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6293 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6295 buildImplicitPart();
6298 void MEDFileStructuredMesh::buildImplicitPart() const
6300 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6302 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6303 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6306 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6308 _faces_if_necessary=0;
6312 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6313 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6315 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6317 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6320 return _faces_if_necessary;
6323 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6325 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6327 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6328 switch(meshDimRelToMax)
6332 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6337 int mdim(cmesh->getMeshDimension());
6339 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6340 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6344 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6348 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6350 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6353 return getNumberOfCellsAtLevel(0);
6356 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6358 if(st.getNumberOfItems()!=1)
6359 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 !");
6360 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6361 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6362 if(getNumberOfNodes()!=(int)nodesFetched.size())
6363 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6364 if(st[0].getPflName().empty())
6366 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6369 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6370 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6371 int sz(nodesFetched.size());
6372 for(const int *work=arr->begin();work!=arr->end();work++)
6374 std::vector<int> conn;
6375 cmesh->getNodeIdsOfCell(*work,conn);
6376 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6377 if(*it>=0 && *it<sz)
6378 nodesFetched[*it]=true;
6380 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6384 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6386 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6390 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6391 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6393 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6394 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6396 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6399 if(!mrs || mrs->isCellFamilyFieldReading())
6401 famCells=DataArrayInt::New();
6402 famCells->alloc(nbOfElt,1);
6403 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6406 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6409 if(!mrs || mrs->isCellNumFieldReading())
6411 numCells=DataArrayInt::New();
6412 numCells->alloc(nbOfElt,1);
6413 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6416 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6419 if(!mrs || mrs->isCellNameFieldReading())
6421 namesCells=DataArrayAsciiChar::New();
6422 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6423 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6424 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6429 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6431 setName(strm->getName());
6432 setDescription(strm->getDescription());
6433 setUnivName(strm->getUnivName());
6434 setIteration(strm->getIteration());
6435 setOrder(strm->getOrder());
6436 setTimeValue(strm->getTime());
6437 setTimeUnit(strm->getTimeUnit());
6438 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6439 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6440 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6443 if(!mrs || mrs->isNodeFamilyFieldReading())
6445 int nbNodes(getNumberOfNodes());
6447 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6448 _fam_nodes=DataArrayInt::New();
6449 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6450 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...
6451 _fam_nodes->fillWithZero();
6452 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6455 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6458 if(!mrs || mrs->isNodeNumFieldReading())
6460 _num_nodes=DataArrayInt::New();
6461 _num_nodes->alloc(nbOfElt,1);
6462 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6465 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6468 if(!mrs || mrs->isNodeNameFieldReading())
6470 _names_nodes=DataArrayAsciiChar::New();
6471 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6472 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6473 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6476 int meshDim(getStructuredMesh()->getMeshDimension());
6477 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6479 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6482 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6484 int meshDim(getStructuredMesh()->getMeshDimension());
6485 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6487 if((const DataArrayInt *)_fam_cells)
6488 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6489 if((const DataArrayInt *)_fam_faces)
6490 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6491 if((const DataArrayInt *)_fam_nodes)
6492 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6493 if((const DataArrayInt *)_num_cells)
6494 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6495 if((const DataArrayInt *)_num_faces)
6496 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6497 if((const DataArrayInt *)_num_nodes)
6498 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6499 if((const DataArrayAsciiChar *)_names_cells)
6501 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6503 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6504 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6505 throw INTERP_KERNEL::Exception(oss.str().c_str());
6507 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6509 if((const DataArrayAsciiChar *)_names_faces)
6511 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6513 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6514 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6515 throw INTERP_KERNEL::Exception(oss.str().c_str());
6517 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6519 if((const DataArrayAsciiChar *)_names_nodes)
6521 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6523 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6524 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6525 throw INTERP_KERNEL::Exception(oss.str().c_str());
6527 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6530 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6534 * Returns an empty instance of MEDFileCMesh.
6535 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6536 * mesh using decrRef() as it is no more needed.
6538 MEDFileCMesh *MEDFileCMesh::New()
6540 return new MEDFileCMesh;
6544 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6545 * file. The first mesh in the file is loaded.
6546 * \param [in] fileName - the name of MED file to read.
6547 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6548 * mesh using decrRef() as it is no more needed.
6549 * \throw If the file is not readable.
6550 * \throw If there is no meshes in the file.
6551 * \throw If the mesh in the file is not a Cartesian one.
6553 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6555 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6556 return New(fid,mrs);
6559 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6561 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6565 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6566 * file. The mesh to load is specified by its name and numbers of a time step and an
6568 * \param [in] fileName - the name of MED file to read.
6569 * \param [in] mName - the name of the mesh to read.
6570 * \param [in] dt - the number of a time step.
6571 * \param [in] it - the number of an iteration.
6572 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6573 * mesh using decrRef() as it is no more needed.
6574 * \throw If the file is not readable.
6575 * \throw If there is no mesh with given attributes in the file.
6576 * \throw If the mesh in the file is not a Cartesian one.
6578 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6580 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6581 return New(fid,mName,dt,it,mrs);
6584 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6586 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6589 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6591 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6594 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6596 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6597 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6602 * Returns the dimension on cells in \a this mesh.
6603 * \return int - the mesh dimension.
6604 * \throw If there are no cells in this mesh.
6606 int MEDFileCMesh::getMeshDimension() const
6608 if(!((const MEDCouplingCMesh*)_cmesh))
6609 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6610 return _cmesh->getMeshDimension();
6614 * Returns the dimension on nodes in \a this mesh.
6615 * \return int - the space dimension.
6616 * \throw If there are no cells in this mesh.
6618 int MEDFileCMesh::getSpaceDimension() const
6620 if(!((const MEDCouplingCMesh*)_cmesh))
6621 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6622 return _cmesh->getSpaceDimension();
6626 * Returns a string describing \a this mesh.
6627 * \return std::string - the mesh information string.
6629 std::string MEDFileCMesh::simpleRepr() const
6631 return MEDFileStructuredMesh::simpleRepr();
6635 * Returns a full textual description of \a this mesh.
6636 * \return std::string - the string holding the mesh description.
6638 std::string MEDFileCMesh::advancedRepr() const
6640 return simpleRepr();
6643 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6645 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6649 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6651 return new MEDFileCMesh;
6654 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6656 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6657 ret->deepCpyEquivalences(*this);
6658 if((const MEDCouplingCMesh*)_cmesh)
6659 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6660 ret->deepCpyAttributes();
6665 * Checks if \a this and another mesh are equal.
6666 * \param [in] other - the mesh to compare with.
6667 * \param [in] eps - a precision used to compare real values.
6668 * \param [in,out] what - the string returning description of unequal data.
6669 * \return bool - \c true if the meshes are equal, \c false, else.
6671 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6673 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6675 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6678 what="Mesh types differ ! This is cartesian and other is NOT !";
6681 clearNonDiscrAttributes();
6682 otherC->clearNonDiscrAttributes();
6683 const MEDCouplingCMesh *coo1=_cmesh;
6684 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6685 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6687 what="Mismatch of cartesian meshes ! One is defined and not other !";
6692 bool ret=coo1->isEqual(coo2,eps);
6695 what="cartesian meshes differ !";
6703 * Clears redundant attributes of incorporated data arrays.
6705 void MEDFileCMesh::clearNonDiscrAttributes() const
6707 MEDFileStructuredMesh::clearNonDiscrAttributes();
6708 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6711 MEDFileCMesh::MEDFileCMesh()
6715 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6718 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6720 catch(INTERP_KERNEL::Exception& e)
6725 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6727 MEDCoupling::MEDCouplingMeshType meshType;
6730 MEDCoupling::MEDCouplingAxisType axType;
6731 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6732 if(meshType!=CARTESIAN)
6734 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6735 throw INTERP_KERNEL::Exception(oss.str().c_str());
6737 MEDFileCMeshL2 loaderl2;
6738 loaderl2.loadAll(fid,mid,mName,dt,it);
6739 setAxisType(axType);
6740 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6743 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6747 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6748 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6750 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6752 synchronizeTinyInfoOnLeaves();
6756 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6758 synchronizeTinyInfoOnLeaves();
6763 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6764 * \param [in] m - the new MEDCouplingCMesh to refer to.
6765 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6768 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6770 dealWithTinyInfo(m);
6776 MEDFileMesh *MEDFileCMesh::cartesianize() const
6778 if(getAxisType()==AX_CART)
6781 return const_cast<MEDFileCMesh *>(this);
6785 const MEDCouplingCMesh *cmesh(getMesh());
6787 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6788 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6789 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6790 clmesh->setCoords(coords);
6791 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6792 ret->MEDFileStructuredMesh::operator=(*this);
6793 ret->setMesh(clmesh);
6794 ret->setAxisType(AX_CART);
6799 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6801 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6802 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6803 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6804 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6805 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6806 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6807 int spaceDim(_cmesh->getSpaceDimension());
6808 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6809 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6810 for(int i=0;i<spaceDim;i++)
6812 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6814 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6815 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
6816 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
6818 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6820 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6821 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6822 for(int i=0;i<spaceDim;i++)
6824 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6825 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6828 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6829 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6832 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6834 const MEDCouplingCMesh *cmesh=_cmesh;
6837 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6838 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6839 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6840 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6843 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6845 return new MEDFileCurveLinearMesh;
6848 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6850 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6853 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6855 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6856 return New(fid,mrs);
6859 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6861 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6862 return New(fid,mName,dt,it,mrs);
6865 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6867 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6870 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6872 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6875 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6877 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6878 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6882 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6884 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6888 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6890 return new MEDFileCurveLinearMesh;
6893 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6895 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6896 ret->deepCpyEquivalences(*this);
6897 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6898 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6899 ret->deepCpyAttributes();
6903 int MEDFileCurveLinearMesh::getMeshDimension() const
6905 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6906 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6907 return _clmesh->getMeshDimension();
6910 std::string MEDFileCurveLinearMesh::simpleRepr() const
6912 return MEDFileStructuredMesh::simpleRepr();
6915 std::string MEDFileCurveLinearMesh::advancedRepr() const
6917 return simpleRepr();
6920 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6922 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6924 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6927 what="Mesh types differ ! This is curve linear and other is NOT !";
6930 clearNonDiscrAttributes();
6931 otherC->clearNonDiscrAttributes();
6932 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6933 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6934 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6936 what="Mismatch of curve linear meshes ! One is defined and not other !";
6941 bool ret=coo1->isEqual(coo2,eps);
6944 what="curve linear meshes differ !";
6951 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6953 MEDFileStructuredMesh::clearNonDiscrAttributes();
6954 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6957 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6959 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6962 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6963 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6964 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6965 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6968 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6970 synchronizeTinyInfoOnLeaves();
6974 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6976 dealWithTinyInfo(m);
6982 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6984 if(getAxisType()==AX_CART)
6987 return const_cast<MEDFileCurveLinearMesh *>(this);
6991 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6993 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6994 const DataArrayDouble *coords(mesh->getCoords());
6996 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6997 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6998 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6999 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7000 mesh2->setCoords(coordsCart);
7001 ret->setMesh(mesh2);
7002 ret->setAxisType(AX_CART);
7007 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7009 synchronizeTinyInfoOnLeaves();
7013 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7017 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7020 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7022 catch(INTERP_KERNEL::Exception& e)
7027 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7029 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7030 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7031 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7032 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7033 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7034 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7035 int spaceDim=_clmesh->getSpaceDimension();
7036 int meshDim=_clmesh->getMeshDimension();
7037 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7038 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7039 const DataArrayDouble *coords=_clmesh->getCoords();
7041 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7042 for(int i=0;i<spaceDim;i++)
7044 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7046 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7047 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
7048 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
7050 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7052 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7053 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7054 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
7055 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
7057 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
7059 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7060 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7063 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7065 MEDCoupling::MEDCouplingMeshType meshType;
7068 MEDCoupling::MEDCouplingAxisType axType;
7069 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7070 setAxisType(axType);
7071 if(meshType!=CURVE_LINEAR)
7073 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7074 throw INTERP_KERNEL::Exception(oss.str().c_str());
7076 MEDFileCLMeshL2 loaderl2;
7077 loaderl2.loadAll(fid,mid,mName,dt,it);
7078 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7081 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7084 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7086 return new MEDFileMeshMultiTS;
7089 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7091 return new MEDFileMeshMultiTS(fid);
7094 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7096 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7100 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7102 return new MEDFileMeshMultiTS(fid,mName);
7105 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7107 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7108 return New(fid,mName);
7111 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7113 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7114 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7116 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7117 if((const MEDFileMesh *)*it)
7118 meshOneTs[i]=(*it)->deepCopy();
7119 ret->_mesh_one_ts=meshOneTs;
7123 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7125 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7128 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7130 std::vector<const BigMemoryObject *> ret;
7131 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7132 ret.push_back((const MEDFileMesh *)*it);
7136 std::string MEDFileMeshMultiTS::getName() const
7138 if(_mesh_one_ts.empty())
7139 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7140 return _mesh_one_ts[0]->getName();
7143 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7145 std::string oldName(getName());
7146 std::vector< std::pair<std::string,std::string> > v(1);
7147 v[0].first=oldName; v[0].second=newMeshName;
7151 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7154 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7156 MEDFileMesh *cur(*it);
7158 ret=cur->changeNames(modifTab) || ret;
7163 void MEDFileMeshMultiTS::cartesianizeMe()
7165 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7167 MEDFileMesh *cur(*it);
7170 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7176 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7178 if(_mesh_one_ts.empty())
7179 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7180 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7183 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7186 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7187 _mesh_one_ts.resize(1);
7188 mesh1TimeStep->incrRef();
7189 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7190 _mesh_one_ts[0]=mesh1TimeStep;
7193 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7195 if ( MEDFileMesh* m = getOneTimeStep() )
7196 return m->getJoints();
7201 * \brief Set Joints that are common to all time-stamps
7203 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7205 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7207 (*it)->setJoints( joints );
7211 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7213 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7214 if((*it).isNotNull())
7215 if((*it)->presenceOfStructureElements())
7220 void MEDFileMeshMultiTS::killStructureElements()
7222 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7223 if((*it).isNotNull())
7224 (*it)->killStructureElements();
7227 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7229 MEDFileJoints *joints(getJoints());
7230 bool jointsWritten(false);
7232 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7234 if ( jointsWritten )
7235 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7237 jointsWritten = true;
7239 (*it)->copyOptionsFrom(*this);
7240 (*it)->writeLL(fid);
7243 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7246 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7248 MEDFileJoints *joints(0);
7249 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7251 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7252 joints = getOneTimeStep()->getJoints();
7254 _mesh_one_ts.clear(); //for the moment to be improved
7255 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7258 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7262 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7265 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7268 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7269 throw INTERP_KERNEL::Exception(oss.str().c_str());
7272 MEDCoupling::MEDCouplingMeshType meshType;
7274 MEDCoupling::MEDCouplingAxisType dummy3;
7275 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7276 loadFromFile(fid,ms.front());
7278 catch(INTERP_KERNEL::Exception& e)
7283 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7286 loadFromFile(fid,mName);
7288 catch(INTERP_KERNEL::Exception& e)
7293 MEDFileMeshes *MEDFileMeshes::New()
7295 return new MEDFileMeshes;
7298 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7300 return new MEDFileMeshes(fid);
7303 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7305 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7309 void MEDFileMeshes::writeLL(med_idt fid) const
7311 checkConsistencyLight();
7312 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7314 (*it)->copyOptionsFrom(*this);
7315 (*it)->writeLL(fid);
7319 // MEDFileMeshes::writ checkConsistencyLight();
7321 int MEDFileMeshes::getNumberOfMeshes() const
7323 return _meshes.size();
7326 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7328 return new MEDFileMeshesIterator(this);
7331 /** Return a borrowed reference (caller is not responsible) */
7332 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7334 if(i<0 || i>=(int)_meshes.size())
7336 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7337 throw INTERP_KERNEL::Exception(oss.str().c_str());
7339 return _meshes[i]->getOneTimeStep();
7342 /** Return a borrowed reference (caller is not responsible) */
7343 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7345 std::vector<std::string> ms=getMeshesNames();
7346 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7349 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7350 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7351 throw INTERP_KERNEL::Exception(oss.str().c_str());
7353 return getMeshAtPos((int)std::distance(ms.begin(),it));
7356 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7358 std::vector<std::string> ret(_meshes.size());
7360 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7362 const MEDFileMeshMultiTS *f=(*it);
7365 ret[i]=f->getName();
7369 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7370 throw INTERP_KERNEL::Exception(oss.str().c_str());
7376 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7379 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7381 MEDFileMeshMultiTS *cur(*it);
7383 ret=cur->changeNames(modifTab) || ret;
7388 void MEDFileMeshes::cartesianizeMe()
7390 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7392 MEDFileMeshMultiTS *cur(*it);
7394 cur->cartesianizeMe();
7398 void MEDFileMeshes::resize(int newSize)
7400 _meshes.resize(newSize);
7403 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7406 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7407 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7408 elt->setOneTimeStep(mesh);
7409 _meshes.push_back(elt);
7412 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7415 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7416 if(i>=(int)_meshes.size())
7417 _meshes.resize(i+1);
7418 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7419 elt->setOneTimeStep(mesh);
7423 void MEDFileMeshes::destroyMeshAtPos(int i)
7425 if(i<0 || i>=(int)_meshes.size())
7427 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7428 throw INTERP_KERNEL::Exception(oss.str().c_str());
7430 _meshes.erase(_meshes.begin()+i);
7433 void MEDFileMeshes::loadFromFile(med_idt fid)
7435 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7437 _meshes.resize(ms.size());
7438 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7439 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7442 MEDFileMeshes::MEDFileMeshes()
7446 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7451 catch(INTERP_KERNEL::Exception& /*e*/)
7455 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7457 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7459 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7460 if((const MEDFileMeshMultiTS *)*it)
7461 meshes[i]=(*it)->deepCopy();
7462 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7463 ret->_meshes=meshes;
7467 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7469 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7472 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7474 std::vector<const BigMemoryObject *> ret;
7475 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7476 ret.push_back((const MEDFileMeshMultiTS *)*it);
7480 std::string MEDFileMeshes::simpleRepr() const
7482 std::ostringstream oss;
7483 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7484 simpleReprWithoutHeader(oss);
7488 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7490 int nbOfMeshes=getNumberOfMeshes();
7491 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7492 std::vector<std::string> mns=getMeshesNames();
7493 for(int i=0;i<nbOfMeshes;i++)
7494 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7497 void MEDFileMeshes::checkConsistencyLight() const
7499 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7501 std::set<std::string> s;
7502 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7504 const MEDFileMeshMultiTS *elt=(*it);
7507 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7508 throw INTERP_KERNEL::Exception(oss.str().c_str());
7510 std::size_t sz=s.size();
7511 s.insert(std::string((*it)->getName()));
7514 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7515 throw INTERP_KERNEL::Exception(oss.str().c_str());
7520 bool MEDFileMeshes::presenceOfStructureElements() const
7522 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7523 if((*it).isNotNull())
7524 if((*it)->presenceOfStructureElements())
7529 void MEDFileMeshes::killStructureElements()
7531 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7532 if((*it).isNotNull())
7533 (*it)->killStructureElements();
7536 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7541 _nb_iter=ms->getNumberOfMeshes();
7545 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7549 MEDFileMesh *MEDFileMeshesIterator::nextt()
7551 if(_iter_id<_nb_iter)
7553 MEDFileMeshes *ms(_ms);
7555 return ms->getMeshAtPos(_iter_id++);
7563 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7565 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7566 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7568 if(geoType==MED_NO_GEOTYPE)
7569 return INTERP_KERNEL::NORM_ERROR;
7570 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7571 throw INTERP_KERNEL::Exception(oss.str());
7573 return typmai2[std::distance(typmai,pos)];
7576 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7586 std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7587 throw INTERP_KERNEL::Exception(oss.str());