1 // Copyright (C) 2007-2023 CEA, EDF
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"
31 #include "MEDCouplingMemArray.txx"
33 #include "InterpKernelAutoPtr.hxx"
38 // From MEDLOader.cxx TU
39 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
40 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
41 extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE];
43 using namespace MEDCoupling;
45 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
47 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
49 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
53 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
55 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
56 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
58 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
59 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
60 ret+=(*it2).capacity();
62 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
63 ret+=(*it).first.capacity()+sizeof(mcIdType);
67 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
69 std::vector<const BigMemoryObject *> ret(1);
70 ret[0]=(const MEDFileEquivalences *)_equiv;
75 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
76 * file. The first mesh in the file is loaded.
77 * \param [in] fileName - the name of MED file to read.
78 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
79 * mesh using decrRef() as it is no more needed.
80 * \throw If the file is not readable.
81 * \throw If there is no meshes in the file.
82 * \throw If the mesh in the file is of a not supported type.
84 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
86 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
90 MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
92 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
95 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
96 throw INTERP_KERNEL::Exception(oss.str().c_str());
98 MEDCoupling::MEDCouplingMeshType meshType;
101 MEDCoupling::MEDCouplingAxisType dummy3;
102 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
103 MCAuto<MEDFileMesh> ret;
108 ret=MEDFileUMesh::New();
113 ret=MEDFileCMesh::New();
118 ret=MEDFileCurveLinearMesh::New();
123 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
124 throw INTERP_KERNEL::Exception(oss.str().c_str());
127 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
132 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
133 * file. The mesh to load is specified by its name and numbers of a time step and an
135 * \param [in] fileName - the name of MED file to read.
136 * \param [in] mName - the name of the mesh to read.
137 * \param [in] dt - the number of a time step.
138 * \param [in] it - the number of an iteration.
139 * \param [in] joints - the sub-domain joints to use instead of those that can be read
140 * from the MED file. Usually this joints are those just read by another iteration
141 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
142 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
143 * mesh using decrRef() as it is no more needed.
144 * \throw If the file is not readable.
145 * \throw If there is no mesh with given attributes in the file.
146 * \throw If the mesh in the file is of a not supported type.
148 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
150 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
151 return New(fid,mName,dt,it,mrs,joints);
154 MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
156 MEDCoupling::MEDCouplingMeshType meshType;
159 MEDCoupling::MEDCouplingAxisType dummy3;
160 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
161 MCAuto<MEDFileMesh> ret;
166 ret=MEDFileUMesh::New();
171 ret=MEDFileCMesh::New();
176 ret=MEDFileCurveLinearMesh::New();
181 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
182 throw INTERP_KERNEL::Exception(oss.str().c_str());
185 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
190 * Writes \a this mesh into an open MED file specified by its descriptor.
191 * \param [in] fid - the MED file descriptor.
192 * \throw If the mesh name is not set.
193 * \throw If the file is open for reading only.
194 * \throw If the writing mode == 1 and the same data is present in an existing file.
196 void MEDFileMesh::writeLL(med_idt fid) const
199 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
201 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
204 const MEDFileEquivalences *eqs(_equiv);
210 * Checks if \a this and another mesh are equal.
211 * \param [in] other - the mesh to compare with.
212 * \param [in] eps - a precision used to compare real values.
213 * \param [in,out] what - the string returning description of unequal data.
214 * \return bool - \c true if the meshes are equal, \c false, else.
216 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
218 if(_order!=other->_order)
220 what="Orders differ !";
223 if(_iteration!=other->_iteration)
225 what="Iterations differ !";
228 if(fabs(_time-other->_time)>eps)
230 what="Time values differ !";
233 if(_dt_unit!=other->_dt_unit)
235 what="Time units differ !";
238 if(_name!=other->_name)
240 what="Names differ !";
243 //univ_name has been ignored -> not a bug because it is a mutable attribute
244 if(_desc_name!=other->_desc_name)
246 what="Description names differ !";
249 if(!areGrpsEqual(other,what))
251 if(!areFamsEqual(other,what))
253 if(!areEquivalencesEqual(other,what))
258 void MEDFileMesh::setName(const std::string& name)
264 * Clears redundant attributes of incorporated data arrays.
266 void MEDFileMesh::clearNonDiscrAttributes() const
271 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
273 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
275 if((*it).first==_name)
285 * Copies data on groups and families from another mesh.
286 * \param [in] other - the mesh to copy the data from.
288 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
290 _groups=other._groups;
291 _families=other._families;
296 * This method clear all the groups in the map.
297 * So this method does not operate at all on arrays.
298 * So this method can lead to orphan families.
300 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
302 void MEDFileMesh::clearGrpMap()
308 * This method clear all the families in the map.
309 * So this method does not operate at all on arrays.
310 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
312 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
314 void MEDFileMesh::clearFamMap()
320 * This method clear all the families and groups in the map.
321 * So this method does not operate at all on arrays.
322 * As all groups and families entry will be removed after
323 * 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.
325 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
327 void MEDFileMesh::clearFamGrpMaps()
334 * Returns names of families constituting a group.
335 * \param [in] name - the name of the group of interest.
336 * \return std::vector<std::string> - a sequence of names of the families.
337 * \throw If the name of a nonexistent group is specified.
339 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
341 std::string oname(name);
342 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
343 if(it==_groups.end())
345 std::vector<std::string> grps=getGroupsNames();
346 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
347 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
348 throw INTERP_KERNEL::Exception(oss.str().c_str());
354 * Returns names of families constituting some groups.
355 * \param [in] grps - a sequence of names of groups of interest.
356 * \return std::vector<std::string> - a sequence of names of the families.
357 * \throw If a name of a nonexistent group is present in \a grps.
359 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
361 std::set<std::string> fams;
362 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
364 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
365 if(it2==_groups.end())
367 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
368 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
369 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
370 throw INTERP_KERNEL::Exception(oss.str().c_str());
372 fams.insert((*it2).second.begin(),(*it2).second.end());
374 std::vector<std::string> fams2(fams.begin(),fams.end());
379 * Returns ids of families constituting a group.
380 * \param [in] name - the name of the group of interest.
381 * \return std::vector<int> - sequence of ids of the families.
382 * \throw If the name of a nonexistent group is specified.
384 std::vector<mcIdType> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
386 std::string oname(name);
387 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
388 std::vector<std::string> grps=getGroupsNames();
389 if(it==_groups.end())
391 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
392 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
393 throw INTERP_KERNEL::Exception(oss.str().c_str());
395 return getFamiliesIds((*it).second);
399 * Sets names of families constituting a group. If data on families of this group is
400 * already present, it is overwritten. Every family in \a fams is checked, and if a
401 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
402 * \param [in] name - the name of the group of interest.
403 * \param [in] fams - a sequence of names of families constituting the group.
405 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
407 std::string oname(name);
409 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
411 std::map<std::string,mcIdType>::iterator it2=_families.find(*it1);
412 if(it2==_families.end())
418 * Sets families constituting a group. The families are specified by their ids.
419 * If a family name is not found by its id, an exception is thrown.
420 * If several families have same id, the first one in lexical order is taken.
421 * \param [in] name - the name of the group of interest.
422 * \param [in] famIds - a sequence of ids of families constituting the group.
423 * \throw If a family name is not found by its id.
425 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<mcIdType>& famIds)
427 std::string oname(name);
428 std::vector<std::string> fams(famIds.size());
430 for(std::vector<mcIdType>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
432 std::string name2=getFamilyNameGivenId(*it1);
439 * Returns names of groups including a given family.
440 * \param [in] name - the name of the family of interest.
441 * \return std::vector<std::string> - a sequence of names of groups including the family.
443 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
445 std::vector<std::string> ret;
446 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
448 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
451 ret.push_back((*it1).first);
459 * Adds an existing family to groups.
460 * \param [in] famName - a name of family to add to \a grps.
461 * \param [in] grps - a sequence of group names to add the family in.
462 * \throw If a family named \a famName not yet exists.
464 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
466 std::string fName(famName);
467 const std::map<std::string,mcIdType>::const_iterator it=_families.find(fName);
468 if(it==_families.end())
470 std::vector<std::string> fams=getFamiliesNames();
471 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
472 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
473 throw INTERP_KERNEL::Exception(oss.str().c_str());
475 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
477 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
478 if(it2!=_groups.end())
479 (*it2).second.push_back(fName);
482 std::vector<std::string> grps2(1,fName);
489 * Returns names of all groups of \a this mesh.
490 * \return std::vector<std::string> - a sequence of group names.
492 std::vector<std::string> MEDFileMesh::getGroupsNames() const
494 std::vector<std::string> ret(_groups.size());
496 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
502 * Returns names of all families of \a this mesh.
503 * \return std::vector<std::string> - a sequence of family names.
505 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
507 std::vector<std::string> ret(_families.size());
509 for(std::map<std::string, mcIdType >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
515 * Returns names of all families of \a this mesh but like they would be in file.
516 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
517 * 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 !
518 * For your information internally in memory such families are renamed to have a nicer API.
520 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
522 std::vector<std::string> ret(getFamiliesNames());
523 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
528 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
529 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
530 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
533 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
535 std::vector<std::string> ret;
536 std::vector<std::string> allGrps(getGroupsNames());
537 const DataArrayIdType *arr=getFamilyFieldAtLevel(meshDimRelToMaxExt);
540 std::set<mcIdType> famIdsInUse(arr->begin(),arr->end());
542 for(auto it : _groups)
544 for(auto it2 : it.second)
546 auto it3 = _families.find( it2 );
547 mcIdType famIdToTest = (*it3).second;
548 if( famIdsInUse.find(famIdToTest) != famIdsInUse.end() )
550 ret.push_back( it.first );
559 * Returns all relative mesh levels (including nodes) where a given group is defined.
560 * \param [in] grp - the name of the group of interest.
561 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
563 std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
565 std::vector<std::string> fams(getFamiliesOnGroup(grp));
566 return getFamsNonEmptyLevelsExt(fams);
570 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
571 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
572 * \param [in] grps - a sequence of names of the groups of interest.
573 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
575 std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
577 std::vector<std::string> fams(getFamiliesOnGroups(grps));
578 return getFamsNonEmptyLevels(fams);
582 * Returns all relative mesh levels (including nodes) where given groups are defined.
583 * \param [in] grps - a sequence of names of the groups of interest.
584 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
586 std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
588 std::vector<std::string> fams(getFamiliesOnGroups(grps));
589 return getFamsNonEmptyLevelsExt(fams);
593 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
594 * To include nodes, call getGrpNonEmptyLevelsExt() method.
595 * \param [in] grp - the name of the group of interest.
596 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
598 std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
600 std::vector<std::string> fams(getFamiliesOnGroup(grp));
601 return getFamsNonEmptyLevels(fams);
605 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
606 * To include nodes, call getFamNonEmptyLevelsExt() method.
607 * \param [in] fam - the name of the family of interest.
608 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
610 std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
612 std::vector<std::string> fams(1,std::string(fam));
613 return getFamsNonEmptyLevels(fams);
617 * Returns all relative mesh levels (including nodes) where a given family is defined.
618 * \param [in] fam - the name of the family of interest.
619 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
621 std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
623 std::vector<std::string> fams(1,std::string(fam));
624 return getFamsNonEmptyLevelsExt(fams);
627 std::string MEDFileMesh::GetMagicFamilyStr()
629 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
633 * Changes a name of every family, included in one group only, to be same as the group name.
634 * \throw If there are families with equal names in \a this mesh.
636 void MEDFileMesh::assignFamilyNameWithGroupName()
638 std::map<std::string, std::vector<std::string> > groups(_groups);
639 std::map<std::string,mcIdType> newFams;
640 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
642 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
643 if(grps.size()==1 && groups[grps[0]].size()==1)
645 if(newFams.find(grps[0])!=newFams.end())
647 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
648 throw INTERP_KERNEL::Exception(oss.str().c_str());
650 newFams[grps[0]]=(*it).second;
651 std::vector<std::string>& grps2=groups[grps[0]];
652 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
657 if(newFams.find((*it).first)!=newFams.end())
659 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
660 throw INTERP_KERNEL::Exception(oss.str().c_str());
662 newFams[(*it).first]=(*it).second;
670 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
672 * \return the removed groups.
674 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
676 std::vector<std::string> ret;
677 std::map<std::string, std::vector<std::string> > newGrps;
678 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
680 if((*it).second.empty())
681 ret.push_back((*it).first);
683 newGrps[(*it).first]=(*it).second;
690 void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name)
692 std::map<std::string, std::vector<std::string> >::iterator it(_groups.find(name));
693 std::vector<std::string> grps(getGroupsNames());
694 if(it==_groups.end())
696 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
697 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
698 throw INTERP_KERNEL::Exception(oss.str().c_str());
700 const std::vector<std::string> &famsOnGrp((*it).second);
701 std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(name));
702 const DataArrayIdType *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt));
705 MCAuto<DataArrayIdType> vals(famArr->getDifferentValues());
706 MCAuto<DataArrayIdType> famIds2(DataArrayIdType::NewFromStdVector(famIds));
707 MCAuto<DataArrayIdType> idsToKill(famIds2->buildIntersection(vals));
708 if(idsToKill->empty())
710 std::vector<std::string> newFamsOnGrp;
711 for(std::vector<std::string>::const_iterator itt=famsOnGrp.begin();itt!=famsOnGrp.end();itt++)
713 if(!idsToKill->presenceOfValue(getFamilyId(*itt)))
714 newFamsOnGrp.push_back(*itt);
716 (*it).second=newFamsOnGrp;
720 * Removes a group from \a this mesh.
721 * \param [in] name - the name of the group to remove.
722 * \throw If no group with such a \a name exists.
724 void MEDFileMesh::removeGroup(const std::string& name)
726 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(name);
727 std::vector<std::string> grps(getGroupsNames());
728 if(it==_groups.end())
730 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
731 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
732 throw INTERP_KERNEL::Exception(oss.str().c_str());
738 * Removes a family from \a this mesh.
739 * \param [in] name - the name of the family to remove.
740 * \throw If no family with such a \a name exists.
742 void MEDFileMesh::removeFamily(const std::string& name)
744 std::string oname(name);
745 std::map<std::string, mcIdType >::iterator it=_families.find(oname);
746 std::vector<std::string> fams=getFamiliesNames();
747 if(it==_families.end())
749 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
750 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
751 throw INTERP_KERNEL::Exception(oss.str().c_str());
754 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
756 std::vector<std::string>& v=(*it3).second;
757 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
764 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
765 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
766 * family field whatever its level. This method also suppresses the orphan families.
768 * \return - The list of removed groups names.
770 * \sa MEDFileMesh::removeOrphanFamilies.
772 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
774 removeOrphanFamilies();
775 return removeEmptyGroups();
779 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
780 * 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.
782 * \return - The list of removed families names.
783 * \sa MEDFileMesh::removeOrphanGroups , MEDFileMesh::removeFamiliesReferedByNoGroups
785 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
787 MCAuto<DataArrayIdType> allFamIdsInUse=computeAllFamilyIdsInUse();
788 std::vector<std::string> ret;
789 if(!((DataArrayIdType*)allFamIdsInUse))
791 ret=getFamiliesNames();
792 _families.clear(); _groups.clear();
795 std::map<std::string,mcIdType> famMap;
796 std::map<std::string, std::vector<std::string> > grps(_groups);
797 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
799 if(allFamIdsInUse->presenceOfValue((*it).second))
800 famMap[(*it).first]=(*it).second;
803 ret.push_back((*it).first);
804 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
805 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
807 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
808 std::vector<std::string>& famv=(*it3).second;
809 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
815 { _families=famMap; _groups=grps; }
820 * 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
821 * this family is orphan or not.
823 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
824 * \sa MEDFileMesh::removeOrphanFamilies
826 void MEDFileMesh::removeFamiliesReferedByNoGroups()
828 std::map<std::string,mcIdType> fams;
829 std::set<std::string> sfams;
830 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
831 sfams.insert((*it).first);
832 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
833 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
835 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
836 if(*it!=DFT_FAM_NAME)
837 _families.erase(*it);
841 * 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
842 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
843 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
845 * 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.
847 * \sa MEDFileMesh::removeOrphanFamilies, MEDFileMesh::zipFamilies
849 void MEDFileMesh::rearrangeFamilies()
851 checkOrphanFamilyZero();
852 removeFamiliesReferedByNoGroups();
854 std::vector<int> levels(getNonEmptyLevelsExt());
855 std::set<mcIdType> idsRefed;
856 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
858 idsRefed.insert((*it).second);
861 if(!getGroupsOnFamily((*it).first).empty())
863 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 !";
864 throw INTERP_KERNEL::Exception(oss.str());
868 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
870 const DataArrayIdType *fams(0);
873 fams=getFamilyFieldAtLevel(*it);
875 catch(INTERP_KERNEL::Exception& ) { }
878 std::vector<bool> v(fams->getNumberOfTuples(),false);
879 for(std::set<mcIdType>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
880 fams->switchOnTupleEqualTo(*pt,v);
881 MCAuto<DataArrayIdType> unfetchedIds(DataArrayIdType::BuildListOfSwitchedOff(v));
882 if(!unfetchedIds->empty())
884 MCAuto<DataArrayIdType> newFams(fams->deepCopy());
885 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
886 setFamilyFieldArr(*it,newFams);
889 removeOrphanFamilies();
893 * This method has no impact on existing groups. This method has only impact on families behind the groups.
894 * This method is especially useful for MED file structures having used too much families to define their groups and that need to be merged without modification of their groups.
895 * To zip families, firstly this method first removes families refered by no groups (see MEDFileMesh::removeFamiliesReferedByNoGroups), then this method puts together families lying on a same set of groups. If the set of families having same groups has a length higher than 1, the families are merged into a single family
896 * having the name of the first family appearing in family definition and with the corresponding family ID.
898 void MEDFileMesh::zipFamilies()
900 checkOrphanFamilyZero();
901 removeFamiliesReferedByNoGroups();
902 std::map< std::set<std::string> , std::vector<std::string> > setOfFamilies;
903 // firstly, store in setOfFamilies as key the common set of groups, and as value the families having such same set of groups
904 for(auto fam : _families)
906 std::vector<std::string> grps( this->getGroupsOnFamily( fam.first ) );
907 std::set<std::string> sgrps(grps.begin(),grps.end());
908 setOfFamilies[sgrps].push_back(fam.first);
911 std::map<std::string, std::vector<std::string> > newGroups(_groups);
912 std::map<std::string,mcIdType> newFams(_families);
913 std::vector<int> levels(getNonEmptyLevelsExt());
914 std::map<mcIdType, std::vector<mcIdType> > famIdsToSubstitute;
915 // iterate on all different set of groups
916 std::set<std::string> familiesToKill;
917 for(auto setOfCommonGrp : setOfFamilies)
919 if( setOfCommonGrp.second.size()<=1 )
921 for(auto fam=setOfCommonGrp.second.begin()+1 ; fam != setOfCommonGrp.second.end() ; fam++)
922 familiesToKill.insert(*fam);
924 // iterate on all different set of groups
925 for(auto setOfCommonGrp : setOfFamilies)
927 if( setOfCommonGrp.second.size()<=1 )
929 std::string newFamName(setOfCommonGrp.second[0]);
930 auto newFamID(_families[newFamName]);
931 for(auto grpToBeModified : setOfCommonGrp.first)
933 std::vector<std::string> newFamiliesForCurGrp(1,newFamName);
934 const std::vector<std::string>& familiesOnCurGrp(_groups[grpToBeModified]);
935 const std::vector<std::string>& familiesToZip(setOfCommonGrp.second);
936 std::for_each(familiesToZip.begin(),familiesToZip.end(),[&famIdsToSubstitute,this,newFamID](const std::string& elt) { famIdsToSubstitute[newFamID].push_back(this->getFamilyId(elt)); });
937 // for each family shared by the current group only keep those not sharing setOfCommonGrp.second
938 std::for_each(familiesOnCurGrp.begin(),familiesOnCurGrp.end(),[&familiesToKill,&newFamiliesForCurGrp](const std::string& elt)
939 { if( familiesToKill.find(elt) == familiesToKill.end() ) { newFamiliesForCurGrp.push_back(elt); } });
940 newGroups[grpToBeModified] = newFamiliesForCurGrp;
942 for(auto familyToKill = setOfCommonGrp.second.begin()+1 ; familyToKill != setOfCommonGrp.second.end(); ++familyToKill)
944 newFams.erase( newFams.find(*familyToKill) );
948 // apply modifications in datastructure
949 for(auto famIdsSubstSession : famIdsToSubstitute)
951 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
953 DataArrayIdType *fams(nullptr);
956 fams=getFamilyFieldAtLevel(*it);
958 catch(INTERP_KERNEL::Exception& ) { }
961 MCAuto<DataArrayIdType> idsToModif(fams->findIdsEqualList(famIdsSubstSession.second.data(),famIdsSubstSession.second.data()+famIdsSubstSession.second.size()));
962 fams->setPartOfValuesSimple3(famIdsSubstSession.first,idsToModif->begin(),idsToModif->end(),0,1,1);
970 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
972 void MEDFileMesh::checkOrphanFamilyZero() const
974 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
976 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
978 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
979 throw INTERP_KERNEL::Exception(oss.str().c_str());
985 * Renames a group in \a this mesh.
986 * \param [in] oldName - a current name of the group to rename.
987 * \param [in] newName - a new group name.
988 * \throw If no group named \a oldName exists in \a this mesh.
989 * \throw If a group named \a newName already exists.
991 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
993 std::string oname(oldName);
994 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
995 std::vector<std::string> grps=getGroupsNames();
996 if(it==_groups.end())
998 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
999 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1000 throw INTERP_KERNEL::Exception(oss.str().c_str());
1002 std::string nname(newName);
1003 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
1004 if(it2!=_groups.end())
1006 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
1007 throw INTERP_KERNEL::Exception(oss.str().c_str());
1009 std::vector<std::string> cpy=(*it).second;
1011 _groups[newName]=cpy;
1015 * Changes an id of a family in \a this mesh.
1016 * This method calls changeFamilyIdArr().
1017 * \param [in] oldId - a current id of the family.
1018 * \param [in] newId - a new family id.
1020 void MEDFileMesh::changeFamilyId(mcIdType oldId, mcIdType newId)
1022 changeFamilyIdArr(oldId,newId);
1023 std::map<std::string,mcIdType> fam2;
1024 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1026 if((*it).second==oldId)
1027 fam2[(*it).first]=newId;
1029 fam2[(*it).first]=(*it).second;
1035 * Renames a family in \a this mesh.
1036 * \param [in] oldName - a current name of the family to rename.
1037 * \param [in] newName - a new family name.
1038 * \throw If no family named \a oldName exists in \a this mesh.
1039 * \throw If a family named \a newName already exists.
1041 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
1043 std::string oname(oldName);
1044 std::map<std::string, mcIdType >::iterator it=_families.find(oname);
1045 std::vector<std::string> fams=getFamiliesNames();
1046 if(it==_families.end())
1048 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
1049 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1050 throw INTERP_KERNEL::Exception(oss.str().c_str());
1052 std::string nname(newName);
1053 std::map<std::string, mcIdType >::iterator it2=_families.find(nname);
1054 if(it2!=_families.end())
1056 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
1057 throw INTERP_KERNEL::Exception(oss.str().c_str());
1059 mcIdType cpy=(*it).second;
1060 _families.erase(it);
1061 _families[newName]=cpy;
1062 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
1064 std::vector<std::string>& v=(*it3).second;
1065 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
1072 * Checks if \a this and another mesh contains the same families.
1073 * \param [in] other - the mesh to compare with \a this one.
1074 * \param [in,out] what - an unused parameter.
1075 * \return bool - \c true if number of families and their ids are the same in the two
1076 * meshes. Families with the id == \c 0 are not considered.
1078 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
1080 if(_families==other->_families)
1082 std::map<std::string,mcIdType> fam0;
1083 std::map<std::string,mcIdType> fam1;
1084 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1086 fam0[(*it).first]=(*it).second;
1087 for(std::map<std::string,mcIdType>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
1089 fam1[(*it).first]=(*it).second;
1094 * Checks if \a this and another mesh contains the same groups.
1095 * \param [in] other - the mesh to compare with \a this one.
1096 * \param [in,out] what - a string describing a difference of groups of the two meshes
1097 * in case if this method returns \c false.
1098 * \return bool - \c true if number of groups and families constituting them are the
1099 * same in the two meshes.
1101 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
1103 if(_groups==other->_groups)
1106 std::size_t sz=_groups.size();
1107 if(sz!=other->_groups.size())
1109 what="Groups differ because not same number !\n";
1114 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
1115 for(std::size_t i=0;i<sz && ret;i++,it1++)
1117 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
1118 if(it2!=other->_groups.end())
1120 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
1121 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1127 what="A group in first mesh exists not in other !\n";
1133 std::ostringstream oss; oss << "Groups description differs :\n";
1134 oss << "First group description :\n";
1135 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1137 oss << " Group \"" << (*it).first << "\" on following families :\n";
1138 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1139 oss << " \"" << *it2 << "\n";
1141 oss << "Second group description :\n";
1142 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1144 oss << " Group \"" << (*it).first << "\" on following families :\n";
1145 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1146 oss << " \"" << *it2 << "\n";
1154 * Checks if a group with a given name exists in \a this mesh.
1155 * \param [in] groupName - the group name.
1156 * \return bool - \c true the group \a groupName exists in \a this mesh.
1158 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1160 std::string grpName(groupName);
1161 return _groups.find(grpName)!=_groups.end();
1165 * Checks if a family with a given id exists in \a this mesh.
1166 * \param [in] famId - the family id.
1167 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1169 bool MEDFileMesh::existsFamily(mcIdType famId) const
1171 for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1172 if((*it2).second==famId)
1178 * Checks if a family with a given name exists in \a this mesh.
1179 * \param [in] familyName - the family name.
1180 * \return bool - \c true the family \a familyName exists in \a this mesh.
1182 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1184 std::string fname(familyName);
1185 return _families.find(fname)!=_families.end();
1189 * Sets an id of a family.
1190 * \param [in] familyName - the family name.
1191 * \param [in] id - a new id of the family.
1193 void MEDFileMesh::setFamilyId(const std::string& familyName, mcIdType id)
1195 std::string fname(familyName);
1196 _families[fname]=id;
1199 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, mcIdType id)
1201 std::string fname(familyName);
1202 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1203 if((*it).second==id)
1205 if((*it).first!=familyName)
1207 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1208 throw INTERP_KERNEL::Exception(oss.str().c_str());
1211 _families[fname]=id;
1215 * Adds a family to \a this mesh.
1216 * \param [in] familyName - a name of the family.
1217 * \param [in] famId - an id of the family.
1218 * \throw If a family with the same name or id already exists in \a this mesh.
1220 void MEDFileMesh::addFamily(const std::string& familyName, mcIdType famId)
1222 std::string fname(familyName);
1223 std::map<std::string,mcIdType>::const_iterator it=_families.find(fname);
1224 if(it==_families.end())
1226 for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1227 if((*it2).second==famId)
1229 std::ostringstream oss;
1230 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1231 throw INTERP_KERNEL::Exception(oss.str().c_str());
1233 _families[fname]=famId;
1237 if((*it).second!=famId)
1239 std::ostringstream oss;
1240 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1241 throw INTERP_KERNEL::Exception(oss.str().c_str());
1247 * Creates a group including all mesh entities of given dimension.
1248 * \warning This method does \b not guarantee that the created group includes mesh
1249 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1250 * present in family fields of different dimensions. To assure this, call
1251 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1252 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1254 * \param [in] groupName - a name of the new group.
1255 * \throw If a group named \a groupName already exists.
1256 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1257 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1259 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1261 std::string grpName(groupName);
1262 std::vector<int> levs=getNonEmptyLevelsExt();
1263 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1265 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1266 oss << "Available relative ext levels are : ";
1267 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1268 throw INTERP_KERNEL::Exception(oss.str().c_str());
1270 if(existsGroup(groupName))
1272 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1273 oss << "Already existing groups are : ";
1274 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1275 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1276 throw INTERP_KERNEL::Exception(oss.str().c_str());
1278 const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1280 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1281 MCAuto<DataArrayIdType> famIds=fieldFamIds->getDifferentValues();
1282 std::vector<std::string> familiesOnWholeGroup;
1283 for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
1286 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1288 _groups[grpName]=familiesOnWholeGroup;
1292 * Ensures that given family ids do not present in family fields of dimensions different
1293 * than given ones. If a family id is present in the family fields of dimensions different
1294 * than the given ones, a new family is created and the whole data is updated accordingly.
1295 * \param [in] famIds - a sequence of family ids to check.
1296 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1297 * famIds should exclusively belong.
1298 * \return bool - \c true if no modification is done in \a this mesh by this method.
1300 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<mcIdType>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1302 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1303 std::vector<int> levs=getNonEmptyLevelsExt();
1304 std::set<int> levs2(levs.begin(),levs.end());
1305 std::vector<int> levsToTest;
1306 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1307 std::set<mcIdType> famIds2(famIds.begin(),famIds.end());
1309 mcIdType maxFamId=1;
1310 if(!_families.empty())
1311 maxFamId=getMaxFamilyId()+1;
1312 std::vector<std::string> allFams=getFamiliesNames();
1313 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1315 const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(*it);
1318 MCAuto<DataArrayIdType> famIds3=fieldFamIds->getDifferentValues();
1319 std::vector<mcIdType> tmp;
1320 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<mcIdType> >(tmp));
1321 for(std::vector<mcIdType>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1324 std::string famName=getFamilyNameGivenId(*it2);
1325 std::ostringstream oss; oss << "Family_" << maxFamId;
1326 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1327 addFamilyOnAllGroupsHaving(famName,zeName);
1328 _families[zeName]=maxFamId;
1329 (const_cast<DataArrayIdType *>(fieldFamIds))->changeValue(*it2,maxFamId);
1338 * Adds a family to a given group in \a this mesh. If the group with a given name does
1339 * not exist, it is created.
1340 * \param [in] grpName - the name of the group to add the family in.
1341 * \param [in] famName - the name of the family to add to the group named \a grpName.
1342 * \throw If \a grpName or \a famName is an empty string.
1343 * \throw If no family named \a famName is present in \a this mesh.
1345 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1347 std::string grpn(grpName);
1348 std::string famn(famName);
1349 if(grpn.empty() || famn.empty())
1350 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1351 std::vector<std::string> fams=getFamiliesNames();
1352 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1354 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1355 oss << "Create this family or choose an existing one ! Existing fams are : ";
1356 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1357 throw INTERP_KERNEL::Exception(oss.str().c_str());
1359 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1360 if(it==_groups.end())
1362 _groups[grpn].push_back(famn);
1366 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1367 if(it2==(*it).second.end())
1368 (*it).second.push_back(famn);
1373 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1374 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1375 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1377 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1379 std::string famNameCpp(famName);
1380 std::string otherCpp(otherFamName);
1381 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1383 std::vector<std::string>& v=(*it).second;
1384 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1386 v.push_back(otherCpp);
1391 void MEDFileMesh::checkNoGroupClash(const DataArrayIdType *famArr, const std::string& grpName) const
1393 std::vector<std::string> grpsNames(getGroupsNames());
1394 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
1396 std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(grpName));
1397 if(famArr->presenceOfValue(famIds))
1399 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
1400 throw INTERP_KERNEL::Exception(oss.str().c_str());
1405 * \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).
1406 * \param [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)
1408 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayIdType *ids, DataArrayIdType *famArr)
1411 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1412 std::string grpName(ids->getName());
1414 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1415 ids->checkStrictlyMonotonic(true);
1416 checkNoGroupClash(famArr,grpName);
1417 MCAuto<DataArrayIdType> famArrTmp; famArrTmp.takeRef(famArr);
1418 std::list< MCAuto<DataArrayIdType> > allFamIds(getAllNonNullFamilyIds());
1419 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1420 MCAuto<DataArrayIdType> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1421 MCAuto<DataArrayIdType> diffFamIds=famIds->getDifferentValues();
1422 std::vector<mcIdType> familyIds;
1423 std::vector< MCAuto<DataArrayIdType> > idsPerfamiliyIds;
1424 mcIdType maxVal=getTheMaxAbsFamilyId()+1;
1425 std::map<std::string,mcIdType> families(_families);
1426 std::map<std::string, std::vector<std::string> > groups(_groups);
1427 std::vector<std::string> fams;
1428 bool created(false);
1429 for(const mcIdType *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1431 MCAuto<DataArrayIdType> ids2Tmp=famIds->findIdsEqual(*famId);
1432 MCAuto<DataArrayIdType> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1433 MCAuto<DataArrayIdType> ids1=famArr->findIdsEqual(*famId);
1434 MCAuto<DataArrayIdType> ret0(ids1->buildSubstractionOptimized(ids2));
1437 bool isFamPresent=false;
1438 for(std::list< MCAuto<DataArrayIdType> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1439 isFamPresent=(*itl)->presenceOfValue(*famId);
1440 if(!isFamPresent && *famId!=0)
1441 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1444 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1445 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1446 fams.push_back(locFamName);
1447 if(existsFamily(*famId))
1449 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1450 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1453 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1457 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1458 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1459 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1460 if(existsFamily(*famId))
1462 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1463 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1468 for(std::size_t i=0;i<familyIds.size();i++)
1470 DataArrayIdType *da=idsPerfamiliyIds[i];
1471 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1474 std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
1475 if(itt!=groups.end())
1477 std::vector<std::string>& famsOnGrp((*itt).second);
1478 famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
1481 groups[grpName]=fams;
1485 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1487 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1490 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1492 std::string fam(familyNameToChange);
1493 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1495 std::vector<std::string>& fams((*it).second);
1496 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1500 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1506 * Returns a name of the family having a given id or, if no such a family exists, creates
1507 * a new uniquely named family and returns its name.
1508 * \param [in] id - the id of the family whose name is required.
1509 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1510 * \return std::string - the name of the existing or the created family.
1511 * \throw If it is not possible to create a unique family name.
1513 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(mcIdType id, bool& created)
1515 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1519 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1520 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1521 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1522 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1524 * This method will throws an exception if it is not possible to create a unique family name.
1526 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,mcIdType>& families, mcIdType id, bool& created)
1528 std::vector<std::string> famAlreadyExisting(families.size());
1530 for(std::map<std::string,mcIdType>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1532 if((*it).second!=id)
1534 famAlreadyExisting[ii]=(*it).first;
1543 std::ostringstream oss; oss << "Family_" << id;
1544 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1550 * Sets names and ids of all families in \a this mesh.
1551 * \param [in] info - a map of a family name to a family id.
1553 void MEDFileMesh::setFamilyInfo(const std::map<std::string,mcIdType>& info)
1559 * Sets names of all groups and families constituting them in \a this mesh.
1560 * \param [in] info - a map of a group name to a vector of names of families
1561 * constituting the group.
1563 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1569 * Returns an id of the family having a given name.
1570 * \param [in] name - the name of the family of interest.
1571 * \return mcIdType - the id of the family of interest.
1572 * \throw If no family with such a \a name exists.
1574 mcIdType MEDFileMesh::getFamilyId(const std::string& name) const
1576 std::map<std::string, mcIdType>::const_iterator it=_families.find(name);
1577 if(it==_families.end())
1579 std::vector<std::string> fams(getFamiliesNames());
1580 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1581 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1582 throw INTERP_KERNEL::Exception(oss.str().c_str());
1584 return (*it).second;
1588 * Returns ids of the families having given names.
1589 * \param [in] fams - a sequence of the names of families of interest.
1590 * \return std::vector<mcIdType> - a sequence of the ids of families of interest.
1591 * \throw If \a fams contains a name of an inexistent family.
1593 std::vector<mcIdType> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1595 std::vector<mcIdType> ret(fams.size());
1597 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1599 std::map<std::string, mcIdType>::const_iterator it2=_families.find(*it);
1600 if(it2==_families.end())
1602 std::vector<std::string> fams2=getFamiliesNames();
1603 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1604 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1605 throw INTERP_KERNEL::Exception(oss.str().c_str());
1607 ret[i]=(*it2).second;
1613 * Returns a maximal abs(id) of families in \a this mesh.
1614 * \return mcIdType - the maximal norm of family id.
1615 * \throw If there are no families in \a this mesh.
1617 mcIdType MEDFileMesh::getMaxAbsFamilyId() const
1619 if(_families.empty())
1620 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1621 mcIdType ret=-std::numeric_limits<mcIdType>::max();
1622 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1624 ret=std::max(std::abs((*it).second),ret);
1630 * Returns a maximal id of families in \a this mesh.
1631 * \return mcIdType - the maximal family id.
1632 * \throw If there are no families in \a this mesh.
1634 mcIdType MEDFileMesh::getMaxFamilyId() const
1636 if(_families.empty())
1637 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1638 mcIdType ret=-std::numeric_limits<mcIdType>::max();
1639 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1641 ret=std::max((*it).second,ret);
1647 * Returns a minimal id of families in \a this mesh.
1648 * \return mcIdType - the minimal family id.
1649 * \throw If there are no families in \a this mesh.
1651 mcIdType MEDFileMesh::getMinFamilyId() const
1653 if(_families.empty())
1654 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1655 mcIdType ret=std::numeric_limits<mcIdType>::max();
1656 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1658 ret=std::min((*it).second,ret);
1664 * Returns a maximal id of families in \a this mesh. Not only named families are
1665 * considered but all family fields as well.
1666 * \return mcIdType - the maximal family id.
1668 mcIdType MEDFileMesh::getTheMaxAbsFamilyId() const
1670 mcIdType m1=-std::numeric_limits<mcIdType>::max();
1671 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1672 m1=std::max(std::abs((*it).second),m1);
1673 mcIdType m2=getMaxAbsFamilyIdInArrays();
1674 return std::max(m1,m2);
1678 * Returns a maximal id of families in \a this mesh. Not only named families are
1679 * considered but all family fields as well.
1680 * \return mcIdType - the maximal family id.
1682 mcIdType MEDFileMesh::getTheMaxFamilyId() const
1684 mcIdType m1=-std::numeric_limits<mcIdType>::max();
1685 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1686 m1=std::max((*it).second,m1);
1687 mcIdType m2=getMaxFamilyIdInArrays();
1688 return std::max(m1,m2);
1692 * Returns a minimal id of families in \a this mesh. Not only named families are
1693 * considered but all family fields as well.
1694 * \return mcIdType - the minimal family id.
1696 mcIdType MEDFileMesh::getTheMinFamilyId() const
1698 mcIdType m1=std::numeric_limits<mcIdType>::max();
1699 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1700 m1=std::min((*it).second,m1);
1701 mcIdType m2=getMinFamilyIdInArrays();
1702 return std::min(m1,m2);
1706 * This method only considers the maps. The contain of family array is ignored here.
1708 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1710 DataArrayIdType *MEDFileMesh::getAllFamiliesIdsReferenced() const
1712 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
1713 std::set<mcIdType> v;
1714 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1715 v.insert((*it).second);
1716 ret->alloc((mcIdType)v.size(),1);
1717 std::copy(v.begin(),v.end(),ret->getPointer());
1722 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1724 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1726 DataArrayIdType *MEDFileMesh::computeAllFamilyIdsInUse() const
1728 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1729 MCAuto<DataArrayIdType> ret;
1730 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1732 const DataArrayIdType *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1733 MCAuto<DataArrayIdType> dv=arr->getDifferentValues();
1734 if((DataArrayIdType *) ret)
1735 ret=dv->buildUnion(ret);
1743 * true is returned if no modification has been needed. false if family
1744 * renumbering has been needed.
1746 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1748 std::vector<int> levs=getNonEmptyLevelsExt();
1749 std::set<mcIdType> allFamIds;
1750 mcIdType maxId=getMaxFamilyId()+1;
1751 std::map<int,std::vector<mcIdType> > famIdsToRenum;
1752 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1754 const DataArrayIdType *fam=getFamilyFieldAtLevel(*it);
1757 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1758 std::set<mcIdType> r2;
1759 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1761 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1762 std::set<mcIdType> r3;
1763 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1766 if(famIdsToRenum.empty())
1768 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1769 for(std::map<int,std::vector<mcIdType> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1771 DataArrayIdType *fam=const_cast<DataArrayIdType *>(getFamilyFieldAtLevel((*it2).first));
1772 mcIdType *famIdsToChange=fam->getPointer();
1773 std::map<mcIdType,mcIdType> ren;
1774 for(std::vector<mcIdType>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1776 if(allIds->presenceOfValue(*it3))
1778 std::string famName=getFamilyNameGivenId(*it3);
1779 std::vector<std::string> grps=getGroupsOnFamily(famName);
1782 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1783 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1784 addFamilyOnGrp((*it4),newFam);
1787 MCAuto<DataArrayIdType> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1788 for(const mcIdType *id=ids->begin();id!=ids->end();id++)
1789 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1795 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1796 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1797 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1798 * This method will throw an exception if a same family id is detected in different level.
1799 * \warning This policy is the opposite of those in MED file documentation ...
1801 void MEDFileMesh::normalizeFamIdsTrio()
1803 ensureDifferentFamIdsPerLevel();
1804 MCAuto<DataArrayIdType> 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,mcIdType> families;
1809 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1812 const DataArrayIdType *fam=getFamilyFieldAtLevel(0);
1816 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1817 std::map<mcIdType,mcIdType> ren;
1818 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
1820 mcIdType nbOfTuples=fam->getNumberOfTuples();
1821 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1822 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1824 for(const mcIdType *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);
1835 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1838 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
1842 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1843 std::map<mcIdType,mcIdType> ren;
1844 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
1846 mcIdType nbOfTuples=fam->getNumberOfTuples();
1847 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1848 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1850 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1852 if(allIds->presenceOfValue(*it))
1854 std::string famName=getFamilyNameGivenId(*it);
1855 families[famName]=ren[*it];
1856 famsFetched.insert(famName);
1861 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1863 DataArrayIdType *fam=const_cast<DataArrayIdType*>(getFamilyFieldAtLevel(*it2));
1866 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1867 fam->fillWithZero();
1868 for(const mcIdType *it3=tmp->begin();it3!=tmp->end();it3++)
1869 if(allIds->presenceOfValue(*it3))
1871 std::string famName=getFamilyNameGivenId(*it3);
1872 families[famName]=0;
1873 famsFetched.insert(famName);
1878 std::vector<std::string> allFams=getFamiliesNames();
1879 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1880 std::set<std::string> unFetchedIds;
1881 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1882 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1883 families[*it4]=_families[*it4];
1888 * This method normalizes fam id with the following policy.
1889 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1890 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1891 * This method will throw an exception if a same family id is detected in different level.
1893 void MEDFileMesh::normalizeFamIdsMEDFile()
1895 ensureDifferentFamIdsPerLevel();
1896 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1897 std::vector<int> levs=getNonEmptyLevelsExt();
1898 std::set<int> levsS(levs.begin(),levs.end());
1899 std::set<std::string> famsFetched;
1900 std::map<std::string,mcIdType> families;
1902 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1905 const DataArrayIdType *fam=getFamilyFieldAtLevel(1);
1908 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1909 std::map<mcIdType,mcIdType> ren;
1910 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
1912 mcIdType nbOfTuples=fam->getNumberOfTuples();
1913 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1914 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1916 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1918 if(allIds->presenceOfValue(*it))
1920 std::string famName=getFamilyNameGivenId(*it);
1921 families[famName]=ren[*it];
1922 famsFetched.insert(famName);
1928 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1930 const DataArrayIdType *fam=getFamilyFieldAtLevel(*it2);
1933 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1934 std::map<mcIdType,mcIdType> ren;
1935 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
1937 mcIdType nbOfTuples=fam->getNumberOfTuples();
1938 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1939 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1941 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1943 if(allIds->presenceOfValue(*it))
1945 std::string famName=getFamilyNameGivenId(*it);
1946 families[famName]=ren[*it];
1947 famsFetched.insert(famName);
1953 std::vector<std::string> allFams=getFamiliesNames();
1954 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1955 std::set<std::string> unFetchedIds;
1956 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1957 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1958 families[*it4]=_families[*it4];
1963 * Returns a name of the family by its id. If there are several families having the given
1964 * id, the name first in lexical order is returned.
1965 * \param [in] id - the id of the family whose name is required.
1966 * \return std::string - the name of the found family.
1967 * \throw If no family with the given \a id exists.
1969 std::string MEDFileMesh::getFamilyNameGivenId(mcIdType id) const
1971 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1972 if((*it).second==id)
1974 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1975 throw INTERP_KERNEL::Exception(oss.str().c_str());
1979 * Returns a string describing \a this mesh. This description includes the mesh name and
1980 * the mesh description string.
1981 * \return std::string - the mesh information string.
1983 std::string MEDFileMesh::simpleRepr() const
1985 std::ostringstream oss;
1986 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1987 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1988 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1993 * Simple loop over MEDFileMesh::addGroup method.
1995 * \sa MEDFileMesh::addGroup
1997 void MEDFileMesh::addGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayIdType *>& grps)
1999 for(auto grp : grps)
2000 this->addGroup(meshDimRelToMaxExt,grp);
2004 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
2005 * an empty one is created.
2007 DataArrayIdType *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
2009 DataArrayIdType *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
2012 MCAuto<DataArrayIdType> arr(DataArrayIdType::New());
2013 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
2014 arr->fillWithZero();
2015 setFamilyFieldArr(meshDimRelToMaxExt,arr);
2016 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
2020 * Returns ids of mesh entities contained in a given group of a given dimension.
2021 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2023 * \param [in] grp - the name of the group of interest.
2024 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2025 * returned instead of ids.
2026 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2027 * numbers, if available and required, of mesh entities of the group. The caller
2028 * is to delete this array using decrRef() as it is no more needed.
2029 * \throw If the name of a nonexistent group is specified.
2030 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2032 DataArrayIdType *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2034 std::vector<std::string> tmp(1);
2036 DataArrayIdType *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
2042 * Returns ids of mesh entities contained in given groups of a given dimension.
2043 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2045 * \param [in] grps - the names of the groups of interest.
2046 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2047 * returned instead of ids.
2048 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2049 * numbers, if available and required, of mesh entities of the groups. The caller
2050 * is to delete this array using decrRef() as it is no more needed.
2051 * \throw If the name of a nonexistent group is present in \a grps.
2052 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2054 DataArrayIdType *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2056 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2057 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
2061 * Returns ids of mesh entities contained in a given family of a given dimension.
2062 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2064 * \param [in] fam - the name of the family of interest.
2065 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2066 * returned instead of ids.
2067 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2068 * numbers, if available and required, of mesh entities of the family. The caller
2069 * is to delete this array using decrRef() as it is no more needed.
2070 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2072 DataArrayIdType *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2074 std::vector<std::string> tmp(1);
2076 DataArrayIdType *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
2082 * Returns ids of nodes contained in a given group.
2083 * \param [in] grp - the name of the group of interest.
2084 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2085 * returned instead of ids.
2086 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2087 * numbers, if available and required, of nodes of the group. The caller
2088 * is to delete this array using decrRef() as it is no more needed.
2089 * \throw If the name of a nonexistent group is specified.
2090 * \throw If the family field is missing for nodes.
2092 DataArrayIdType *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
2094 std::vector<std::string> tmp(1);
2096 DataArrayIdType *ret=getNodeGroupsArr(tmp,renum);
2102 * Returns ids of nodes contained in given groups.
2103 * \param [in] grps - the names of the groups of interest.
2104 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2105 * returned instead of ids.
2106 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2107 * numbers, if available and required, of nodes of the groups. The caller
2108 * is to delete this array using decrRef() as it is no more needed.
2109 * \throw If the name of a nonexistent group is present in \a grps.
2110 * \throw If the family field is missing for nodes.
2112 DataArrayIdType *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
2114 return getGroupsArr(1,grps,renum);
2118 * Returns ids of nodes contained in a given family.
2119 * \param [in] fam - the name of the family of interest.
2120 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2121 * returned instead of ids.
2122 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2123 * numbers, if available and required, of nodes of the family. The caller
2124 * is to delete this array using decrRef() as it is no more needed.
2125 * \throw If the name of a nonexistent family is specified.
2126 * \throw If the family field is missing for nodes.
2128 DataArrayIdType *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
2130 std::vector<std::string> tmp(1);
2132 DataArrayIdType *ret=getNodeFamiliesArr(tmp,renum);
2138 * Returns ids of nodes contained in given families.
2139 * \param [in] fams - the names of the families of interest.
2140 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2141 * returned instead of ids.
2142 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2143 * numbers, if available and required, of nodes of the families. The caller
2144 * is to delete this array using decrRef() as it is no more needed.
2145 * \throw If the family field is missing for nodes.
2147 DataArrayIdType *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2149 return getFamiliesArr(1,fams,renum);
2153 * Adds groups of given dimension and creates corresponding families and family fields
2154 * given ids of mesh entities of each group.
2155 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2156 * \param [in] grps - a sequence of arrays of ids each describing a group.
2157 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2159 * \throw If names of some groups in \a grps are equal.
2160 * \throw If \a grps includes a group with an empty name.
2161 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2162 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2164 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayIdType *>& grps, bool renum)
2168 std::set<std::string> grpsName;
2169 std::vector<std::string> grpsName2(grps.size());
2172 for(std::vector<const DataArrayIdType *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2174 grpsName.insert((*it)->getName());
2175 grpsName2[i]=(*it)->getName();
2177 if(grpsName.size()!=grps.size())
2178 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2179 if(grpsName.find(std::string(""))!=grpsName.end())
2180 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2181 mcIdType sz=getSizeAtLevel(meshDimRelToMaxExt);
2182 MCAuto<DataArrayIdType> fam;
2183 std::vector< std::vector<mcIdType> > fidsOfGroups;
2186 fam=DataArrayIdType::MakePartition(grps,sz,fidsOfGroups);
2190 std::vector< MCAuto<DataArrayIdType> > grps2(grps.size());
2191 for(unsigned int ii=0;ii<grps.size();ii++)
2193 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2194 grps2[ii]->setName(grps[ii]->getName());
2196 std::vector<const DataArrayIdType *> grps3(grps2.begin(),grps2.end());
2197 fam=DataArrayIdType::MakePartition(grps3,sz,fidsOfGroups);
2200 if(!_families.empty())
2201 offset=getMaxAbsFamilyId()+1;
2202 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2203 MCAuto<DataArrayIdType> ids=fam->getDifferentValues();
2204 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2205 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2209 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2210 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2211 * For the moment, the two last input parameters are not taken into account.
2213 void MEDFileMesh::appendFamilyEntries(const DataArrayIdType *famIds, const std::vector< std::vector<mcIdType> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2215 std::map<mcIdType,std::string> famInv;
2216 for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
2218 std::ostringstream oss;
2219 oss << "Family_" << (*it);
2220 _families[oss.str()]=(*it);
2221 famInv[*it]=oss.str();
2224 for(std::vector< std::vector<mcIdType> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2226 for(std::vector<mcIdType>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2228 _groups[grpNames[i]].push_back(famInv[*it2]);
2233 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2235 std::vector<int> levs(getNonEmptyLevels());
2236 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2237 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2239 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2240 ret.insert(ret.end(),elts.begin(),elts.end());
2246 * \sa getAllDistributionOfTypes
2248 std::vector<mcIdType> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2250 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2251 return mLev->getDistributionOfTypes();
2254 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2256 loadLL(fid,mName,dt,it,mrs);
2257 loadJointsFromFile(fid);
2258 loadEquivalences(fid);
2261 void MEDFileMesh::TranslateFamilyIds(mcIdType offset, DataArrayIdType *famArr, std::vector< std::vector<mcIdType> >& famIdsPerGrp)
2263 famArr->applyLin(offset>0?1:-1,offset,0);
2264 for(std::vector< std::vector<mcIdType> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2267 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<mcIdType>());
2268 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind(std::plus<mcIdType>(),std::placeholders::_1,offset));
2273 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2274 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2275 * If this method fails to find such a name it will throw an exception.
2277 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2280 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2283 std::size_t len=nameTry.length();
2284 for(std::size_t ii=1;ii<len;ii++)
2286 std::string tmp=nameTry.substr(ii,len-ii);
2287 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2293 for(char i=1;i<30;i++)
2295 std::string tmp1(nameTry.at(0),i);
2297 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2303 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2305 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2307 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2310 mcIdType MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<mcIdType>& code, mcIdType strt)
2312 std::size_t nbOfChunks=code.size()/3;
2313 if(code.size()%3!=0)
2314 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2316 for(std::size_t i=0;i<nbOfChunks;i++)
2325 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2326 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2327 * If _name is not empty and that 'm' has the same name nothing is done.
2328 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2330 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2333 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2338 std::string name(m->getName());
2343 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2344 oss << name << "' ! Names must match !";
2345 throw INTERP_KERNEL::Exception(oss.str().c_str());
2349 if(_desc_name.empty())
2350 _desc_name=m->getDescription();
2353 std::string name(m->getDescription());
2356 if(_desc_name!=name)
2358 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2359 oss << name << "' ! Names must match !";
2360 throw INTERP_KERNEL::Exception(oss.str().c_str());
2366 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2368 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2369 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
2371 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2372 oss << " - Groups lying on this family : ";
2373 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2374 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2375 oss << std::endl << std::endl;
2380 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2381 * file. The mesh to load is specified by its name and numbers of a time step and an
2383 * \param [in] fileName - the name of MED file to read.
2384 * \param [in] mName - the name of the mesh to read.
2385 * \param [in] dt - the number of a time step.
2386 * \param [in] it - the number of an iteration.
2387 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2388 * mesh using decrRef() as it is no more needed.
2389 * \throw If the file is not readable.
2390 * \throw If there is no mesh with given attributes in the file.
2391 * \throw If the mesh in the file is not an unstructured one.
2393 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2395 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2396 return New(fid,mName,dt,it,mrs);
2399 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2401 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2405 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2406 * file. The first mesh in the file is loaded.
2407 * \param [in] fileName - the name of MED file to read.
2408 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2409 * mesh using decrRef() as it is no more needed.
2410 * \throw If the file is not readable.
2411 * \throw If there is no meshes in the file.
2412 * \throw If the mesh in the file is not an unstructured one.
2414 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2416 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2417 return New(fid,mrs);
2421 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2423 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2426 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2427 throw INTERP_KERNEL::Exception(oss.str().c_str());
2430 MEDCoupling::MEDCouplingMeshType meshType;
2432 MEDCoupling::MEDCouplingAxisType dummy3;
2433 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2434 return T::New(fid,ms.front(),dt,it,mrs);
2437 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2439 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2443 * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2444 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2446 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2449 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2450 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2451 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2452 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2454 m2D->setCoords(m3D->getCoords());
2455 ret->setMeshAtLevel(0,m3D);
2456 ret->setMeshAtLevel(-1,m2D);
2457 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<med_int>::max()-mem->get2DCellIdForExtrusion());
2462 * Returns an empty instance of MEDFileUMesh.
2463 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2464 * mesh using decrRef() as it is no more needed.
2466 MEDFileUMesh *MEDFileUMesh::New()
2468 return new MEDFileUMesh;
2472 * Please refer to the other MEDFileUMesh::LoadConnectivityOnlyPartOf method that has the same semantic and the same parameter (excepted the first).
2473 * This method is \b NOT wrapped into python.
2475 MCAuto<MEDFileUMesh> MEDFileUMesh::LoadConnectivityOnlyPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2477 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2478 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,[](MEDFileUMeshL2& loader,med_idt fid, MeshOrStructMeshCls *mid,const std::string& mName,const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>&slicPerTyp,int dt,int it,MEDFileMeshReadSelector *mrs){ int Mdim; loader.loadPartConnectivityOnly(fid,mid,mName,types,slicPerTyp,dt,it,mrs,Mdim); },dt,it,mrs);
2483 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2484 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2485 * \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.
2486 * 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
2487 * at most the memory consumtion. Contrary to MEDFileUMesh::LoadPart this method does not load coordinates but only connectivities
2489 * \param [in] fileName - the name of the file.
2490 * \param [in] mName - the name of the mesh to be read.
2491 * \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.
2492 * \param [in] slicPerTyp - 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.
2493 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2494 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2495 * \param [in] mrs - the request for what to be loaded.
2496 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2497 * \sa MEDFileUMesh::LoadPartOf
2499 MCAuto<MEDFileUMesh> MEDFileUMesh::LoadConnectivityOnlyPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2501 MEDFileUtilities::CheckFileForRead(fileName);
2502 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2503 return MEDFileUMesh::LoadConnectivityOnlyPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2507 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2508 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2509 * \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.
2510 * 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
2511 * at most the memory consumtion.
2513 * \param [in] fileName - the name of the file.
2514 * \param [in] mName - the name of the mesh to be read.
2515 * \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.
2516 * \param [in] slicPerTyp - 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.
2517 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2518 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2519 * \param [in] mrs - the request for what to be loaded.
2520 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2521 * \sa MEDFileUMesh::LoadConnectivityOnlyPartOf
2523 MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2525 MEDFileUtilities::CheckFileForRead(fileName);
2526 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2527 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2531 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2532 * This method is \b NOT wrapped into python.
2534 MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2536 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2537 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,[](MEDFileUMeshL2& loader,med_idt fid, MeshOrStructMeshCls *mid,const std::string& mName,const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>&slicPerTyp,int dt,int it,MEDFileMeshReadSelector *mrs){ loader.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs); },dt,it,mrs);
2542 * This method loads from file with name \a fileName a part of the mesh called \a mName as MEDFileUMesh::LoadPartOf does. The difference is that
2543 * here we are not limited to slice of cells, but we can potentially load a random selection of cells, defined in the \a distrib vector.
2544 * \param [in] fid - id of the file
2545 * \param [in] mName - the name of the mesh to be read
2546 * \param [in] distrib - map defining for each geometric type, the corresponding vector of cells we want to load with c-type indexing (starting from zero).
2547 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2548 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2549 * \param [in] mrs - the request for what to be loaded.
2550 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2552 MEDFileUMesh *MEDFileUMesh::LoadPartOfFromUserDistrib(med_idt fid, const std::string& mName, const std::map<INTERP_KERNEL::NormalizedCellType,std::vector<mcIdType>>& distrib, int dt, int it, MEDFileMeshReadSelector *mrs)
2554 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2555 ret->loadPartUMeshFromFileFromUserDistrib(fid,mName,distrib,[](MEDFileUMeshL2& loader,med_idt fid, MeshOrStructMeshCls *mid,const std::string& mName,const std::map<INTERP_KERNEL::NormalizedCellType,std::vector<mcIdType>>& distrib,int dt,int it,MEDFileMeshReadSelector *mrs){ loader.loadPartFromUserDistrib(fid,mid,mName,distrib,dt,it,mrs); },dt,it,mrs);
2560 * This method is an helper to load only consecutive nodes chunk of data of MED file pointed by \a fileName.
2561 * Consecutive chunk is specified classicaly by start (included) stop (excluded) format with \a startNodeId and \a stopNodeId respectively.
2562 * This method returns 5 elements.
2564 * \param [in] fileName - Name of file nodes to be read of.
2565 * \param [in] mName - Name of the mesh inside file pointed be \a fileName nodes to be read of.
2566 * \param [in] dt - Time iteration inside file pointed be \a fileName nodes to be read of.
2567 * \param [in] it - Time order inside file pointed be \a fileName nodes to be read of.
2568 * \param [in] infosOnComp - Components info of nodes to be read of. The size of string vector should be equal to space dimension of mesh to be read.
2569 * \param [in] startNodeId - Start Node Id (included) of chunk of data to be read
2570 * \param [in] stopNodeId - Start Node Id (included) of chunk of data to be read
2571 * \param [out] coords - output coordinates of requested chunk (DataArrayDouble)
2572 * \param [out] partCoords - output PartDefinition object of chunk
2573 * \param [out] famCoords - output family id field of requested chunk (DataArrayIdType)
2574 * \param [out] numCoords - output num id field of requested chunk (DataArrayIdType)
2575 * \param [out] nameCoords - output names on nodes of requested chunk (DataArrayAsciiChar)
2577 * \sa MEDLoaderUMesh::LoadPartOf
2579 void MEDFileUMesh::LoadPartCoords(const std::string& fileName, const std::string& mName, int dt, int it, const std::vector<std::string>& infosOnComp, mcIdType startNodeId, mcIdType stopNodeId,
2580 MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<DataArrayIdType>& famCoords, MCAuto<DataArrayIdType>& numCoords, MCAuto<DataArrayAsciiChar>& nameCoords)
2582 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2583 MEDFileUMeshL2::LoadPartCoords(fid,infosOnComp,mName,dt,it,startNodeId,stopNodeId,coords,partCoords,famCoords,numCoords,nameCoords);
2586 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2588 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2589 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2593 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2595 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2596 ret.push_back((const DataArrayDouble*)_coords);
2597 ret.push_back((const DataArrayIdType *)_fam_coords);
2598 ret.push_back((const DataArrayIdType *)_num_coords);
2599 ret.push_back((const DataArrayIdType *)_global_num_coords);
2600 ret.push_back((const DataArrayIdType *)_rev_num_coords);
2601 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2602 ret.push_back((const PartDefinition *)_part_coords);
2603 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2604 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2605 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2606 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2610 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2612 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2616 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2618 return new MEDFileUMesh;
2621 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2623 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2624 ret->deepCpyEquivalences(*this);
2625 if(_coords.isNotNull())
2626 ret->_coords=_coords->deepCopy();
2627 if(_fam_coords.isNotNull())
2628 ret->_fam_coords=_fam_coords->deepCopy();
2629 if(_num_coords.isNotNull())
2630 ret->_num_coords=_num_coords->deepCopy();
2631 if(_global_num_coords.isNotNull())
2632 ret->_global_num_coords=_global_num_coords->deepCopy();
2633 if(_rev_num_coords.isNotNull())
2634 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2635 if(_name_coords.isNotNull())
2636 ret->_name_coords=_name_coords->deepCopy();
2638 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2640 if((const MEDFileUMeshSplitL1 *)(*it))
2641 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2643 if((const PartDefinition*)_part_coords)
2644 ret->_part_coords=_part_coords->deepCopy();
2649 * Checks if \a this and another mesh are equal.
2650 * \param [in] other - the mesh to compare with.
2651 * \param [in] eps - a precision used to compare real values.
2652 * \param [in,out] what - the string returning description of unequal data.
2653 * \return bool - \c true if the meshes are equal, \c false, else.
2655 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2657 if(!MEDFileMesh::isEqual(other,eps,what))
2659 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2662 what="Mesh types differ ! This is unstructured and other is NOT !";
2665 clearNonDiscrAttributes();
2666 otherC->clearNonDiscrAttributes();
2667 const DataArrayDouble *coo1=_coords;
2668 const DataArrayDouble *coo2=otherC->_coords;
2669 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2671 what="Mismatch of coordinates ! One is defined and not other !";
2676 bool ret=coo1->isEqual(*coo2,eps);
2679 what="Coords differ !";
2684 const DataArrayIdType *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2685 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2687 what="Mismatch of families arr on nodes ! One is defined and not other !";
2692 bool ret=famc1->isEqual(*famc2);
2695 what="Families arr on node differ !";
2701 const DataArrayIdType *numc1(_num_coords),*numc2(otherC->_num_coords);
2702 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2704 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2709 bool ret=numc1->isEqual(*numc2);
2712 what="Numbering arr on node differ !";
2718 const DataArrayIdType *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2719 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2721 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2726 bool ret=gnumc1->isEqual(*gnumc2);
2729 what="Global numbering arr on node differ !";
2735 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2736 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2738 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2743 bool ret=namec1->isEqual(*namec2);
2746 what="Names arr on node differ !";
2751 if(_ms.size()!=otherC->_ms.size())
2753 what="Number of levels differs !";
2756 std::size_t sz=_ms.size();
2757 for(std::size_t i=0;i<sz;i++)
2759 const MEDFileUMeshSplitL1 *s1=_ms[i];
2760 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2761 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2763 what="Mismatch of presence of sub levels !";
2768 bool ret=s1->isEqual(s2,eps,what);
2773 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2776 if((!pd0 && pd1) || (pd0 && !pd1))
2778 what=std::string("node part def is defined only for one among this or other !");
2781 return pd0->isEqual(pd1,what);
2785 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2786 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2787 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2788 * \throw if internal family array is inconsistent
2789 * \sa checkSMESHConsistency()
2791 void MEDFileUMesh::checkConsistency() const
2793 if(!_coords || !_coords->isAllocated())
2796 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2798 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2799 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2800 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2804 mcIdType nbCoo = _coords->getNumberOfTuples();
2805 if (_fam_coords.isNotNull())
2806 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2807 if (_num_coords.isNotNull())
2809 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2811 mcIdType maxValue=_num_coords->getMaxValue(pos);
2812 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2813 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2815 if (_global_num_coords.isNotNull())
2817 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2819 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2820 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2821 if (_num_coords && !_num_coords->hasUniqueValues())
2822 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2824 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2825 // Now sub part check:
2826 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2827 it != _ms.end(); it++)
2828 (*it)->checkConsistency();
2833 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2834 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2835 * entities as it likes), or non overlapping between all sub-levels.
2836 * \throw if the condition above is not respected
2838 void MEDFileUMesh::checkSMESHConsistency() const
2841 // For all sub-levels, numbering is either always null or with void intersection:
2844 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2845 std::vector< const DataArrayIdType * > v;
2846 bool voidOrNot = ((*it)->_num == 0);
2847 for (it++; it != _ms.end(); it++)
2848 if( ((*it)->_num == 0) != voidOrNot )
2849 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2850 else if (!voidOrNot)
2851 v.push_back((*it)->_num);
2854 // don't forget the 1st one:
2855 v.push_back(_ms[0]->_num);
2856 MCAuto<DataArrayIdType> inter = DataArrayIdType::BuildIntersection(v);
2857 if (inter->getNumberOfTuples())
2858 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2864 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2865 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2867 void MEDFileUMesh::clearNodeAndCellNumbers()
2869 _num_coords.nullify();
2870 _rev_num_coords.nullify();
2871 _global_num_coords.nullify();
2872 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2874 (*it)->_num.nullify();
2875 (*it)->_rev_num.nullify();
2876 (*it)->_global_num.nullify();
2881 * Clears redundant attributes of incorporated data arrays.
2883 void MEDFileUMesh::clearNonDiscrAttributes() const
2885 MEDFileMesh::clearNonDiscrAttributes();
2886 if(_coords.isNotNull())
2887 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2888 if(_fam_coords.isNotNull())
2889 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2890 if(_num_coords.isNotNull())
2891 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2892 if(_name_coords.isNotNull())
2893 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2894 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2896 if((*it).isNotNull())
2897 (*it)->clearNonDiscrAttributes();
2901 void MEDFileUMesh::setName(const std::string& name)
2903 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2904 if((*it).isNotNull())
2905 (*it)->setName(name);
2906 MEDFileMesh::setName(name);
2909 MEDFileUMesh::MEDFileUMesh()
2913 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2916 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2918 catch(INTERP_KERNEL::Exception& e)
2924 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2925 * See MEDFileUMesh::LoadPartOf for detailed description.
2929 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp,
2930 std::function<void(MEDFileUMeshL2&,med_idt fid, MeshOrStructMeshCls *,const std::string&, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>&,int,int,MEDFileMeshReadSelector *)> functorOnUMeshL2, int dt, int it, MEDFileMeshReadSelector *mrs)
2932 MEDFileUMeshL2 loaderl2;
2933 MEDCoupling::MEDCouplingMeshType meshType;
2936 MEDCoupling::MEDCouplingAxisType dummy3;
2937 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2938 if(meshType!=UNSTRUCTURED)
2940 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2941 throw INTERP_KERNEL::Exception(oss.str().c_str());
2943 functorOnUMeshL2(loaderl2,fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2944 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2948 * This method loads only a part of specified cells in the \a distrib map vector
2949 * See MEDFileUMesh::LoadPartOfFromUserDistrib for detailed description.
2953 void MEDFileUMesh::loadPartUMeshFromFileFromUserDistrib(med_idt fid, const std::string& mName, const std::map<INTERP_KERNEL::NormalizedCellType,std::vector<mcIdType>>& distrib,
2954 std::function<void(MEDFileUMeshL2&,med_idt fid, MeshOrStructMeshCls *,const std::string&,const std::map<INTERP_KERNEL::NormalizedCellType,std::vector<mcIdType>>&,int,int,MEDFileMeshReadSelector *)> functorOnUMeshL2,
2955 int dt, int it, MEDFileMeshReadSelector *mrs)
2957 MEDFileUMeshL2 loaderl2;
2958 MEDCoupling::MEDCouplingMeshType meshType;
2961 MEDCoupling::MEDCouplingAxisType dummy3;
2962 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2963 if(meshType!=UNSTRUCTURED)
2965 std::ostringstream oss; oss << "loadPartUMeshFromFileFromUserDistrib : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2966 throw INTERP_KERNEL::Exception(oss.str().c_str());
2968 functorOnUMeshL2(loaderl2,fid,mid,mName,distrib,dt,it,mrs);
2969 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2974 * \brief Write joints in a file
2976 void MEDFileMesh::writeJoints(med_idt fid) const
2978 if ( _joints.isNotNull() )
2979 _joints->writeLL(fid);
2983 * \brief Load joints in a file or use provided ones
2985 //================================================================================
2987 * \brief Load joints in a file or use provided ones
2988 * \param [in] fid - MED file descriptor
2989 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2990 * Usually this joints are those just read by another iteration
2991 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2993 //================================================================================
2995 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2997 if ( toUseInstedOfReading )
2998 setJoints( toUseInstedOfReading );
3000 _joints = MEDFileJoints::New( fid, _name );
3003 void MEDFileMesh::loadEquivalences(med_idt fid)
3005 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
3007 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
3010 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
3012 const MEDFileEquivalences *equiv(other._equiv);
3014 _equiv=equiv->deepCopy(this);
3017 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
3019 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
3020 if(!thisEq && !otherEq)
3022 if(thisEq && otherEq)
3023 return thisEq->isEqual(otherEq,what);
3026 what+="Equivalence differs : defined in this and not in other (or reversely) !";
3031 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
3033 const MEDFileEquivalences *equiv(_equiv);
3036 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
3037 _equiv->getRepr(oss);
3040 void MEDFileMesh::checkCartesian() const
3042 if(getAxisType()!=AX_CART)
3044 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()) << ").";
3045 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
3046 oss << " - call setAxisType(AX_CART)" << std::endl;
3047 oss << " - call cartesianize()";
3048 throw INTERP_KERNEL::Exception(oss.str().c_str());
3053 * \brief Return number of joints, which is equal to number of adjacent mesh domains
3055 int MEDFileMesh::getNumberOfJoints() const
3057 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
3061 * \brief Return joints with all adjacent mesh domains
3063 MEDFileJoints * MEDFileMesh::getJoints() const
3065 return const_cast<MEDFileJoints*>(& (*_joints));
3068 void MEDFileMesh::setJoints( MEDFileJoints* joints )
3070 if ( joints != _joints )
3079 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
3081 * \sa loadPartUMeshFromFile
3083 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
3085 MEDFileUMeshL2 loaderl2;
3086 MEDCoupling::MEDCouplingMeshType meshType;
3089 MEDCoupling::MEDCouplingAxisType axType;
3090 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
3091 setAxisType(axType);
3092 if(meshType!=UNSTRUCTURED)
3094 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
3095 throw INTERP_KERNEL::Exception(oss.str().c_str());
3097 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
3098 dispatchLoadedPart(fid,loaderl2,mName,mrs);
3099 // Structure element part...
3100 med_int nModels(-1);
3102 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
3103 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
3107 _elt_str.resize(nModels);
3108 for(int i=0;i<nModels;i++)
3109 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
3112 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
3114 int lev=loaderl2.getNumberOfLevels();
3116 for(int i=0;i<lev;i++)
3118 if(!loaderl2.emptyLev(i))
3119 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
3123 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
3125 setName(loaderl2.getName());
3126 setDescription(loaderl2.getDescription());
3127 setUnivName(loaderl2.getUnivName());
3128 setIteration(loaderl2.getIteration());
3129 setOrder(loaderl2.getOrder());
3130 setTimeValue(loaderl2.getTime());
3131 setTimeUnit(loaderl2.getTimeUnit());
3132 _coords=loaderl2.getCoords();
3133 if(!mrs || mrs->isNodeFamilyFieldReading())
3134 _fam_coords=loaderl2.getCoordsFamily();
3135 if(!mrs || mrs->isNodeNumFieldReading())
3136 _num_coords=loaderl2.getCoordsNum();
3137 if(!mrs || mrs->isNodeNameFieldReading())
3138 _name_coords=loaderl2.getCoordsName();
3139 if(!mrs || mrs->isGlobalNodeNumFieldReading())
3140 _global_num_coords=loaderl2.getCoordsGlobalNum();
3141 _part_coords=loaderl2.getPartDefOfCoo();
3144 MEDFileUMesh::~MEDFileUMesh()
3148 void MEDFileUMesh::writeMeshLL(med_idt fid) const
3150 const DataArrayDouble *coo=_coords;
3151 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3152 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3153 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3154 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3155 int spaceDim=(int)(coo?coo->getNumberOfComponents():0);
3158 mdim=getMeshDimension();
3159 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3160 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3161 for(int i=0;i<spaceDim;i++)
3163 std::string info=coo->getInfoOnComponent(i);
3165 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3166 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
3167 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
3169 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
3171 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
3172 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
3173 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
3174 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3177 (*it)->checkCoordsConsistency(coo);
3178 (*it)->write(fid,meshName,mdim);
3180 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
3184 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
3185 * \return std::vector<int> - a sequence of the relative dimensions.
3187 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
3189 std::vector<int> ret;
3191 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3192 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3199 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
3200 * \return std::vector<int> - a sequence of the relative dimensions.
3202 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
3204 std::vector<int> ret0=getNonEmptyLevels();
3205 if((const DataArrayDouble *) _coords)
3207 std::vector<int> ret(ret0.size()+1);
3209 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3215 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
3217 std::vector<int> ret;
3218 const DataArrayIdType *famCoo(_fam_coords);
3222 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3224 const MEDFileUMeshSplitL1 *cur(*it);
3226 if(cur->getFamilyField())
3232 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3234 std::vector<int> ret;
3235 if(_num_coords.isNotNull())
3238 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3240 const MEDFileUMeshSplitL1 *cur(*it);
3242 if(cur->getNumberField())
3248 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3250 std::vector<int> ret;
3251 const DataArrayAsciiChar *nameCoo(_name_coords);
3255 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3257 const MEDFileUMeshSplitL1 *cur(*it);
3259 if(cur->getNameField())
3266 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3267 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3268 * \param [in] fams - the name of the family of interest.
3269 * \return std::vector<int> - a sequence of the relative dimensions.
3271 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3273 std::vector<mcIdType> ret;
3274 std::vector<int> levs(getNonEmptyLevels());
3275 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3276 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3277 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3283 * Returns all relative mesh levels (including nodes) where given families are defined.
3284 * \param [in] fams - the names of the families of interest.
3285 * \return std::vector<int> - a sequence of the relative dimensions.
3287 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3289 std::vector<mcIdType> ret0(getFamsNonEmptyLevels(fams));
3290 const DataArrayIdType *famCoords(_fam_coords);
3293 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3294 if(famCoords->presenceOfValue(famIds))
3296 std::vector<mcIdType> ret(ret0.size()+1);
3298 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3305 mcIdType MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3307 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3308 if((const DataArrayIdType *)_fam_coords)
3310 mcIdType val=_fam_coords->getMaxValue(tmp);
3311 ret=std::max(ret,std::abs(val));
3313 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3315 if((const MEDFileUMeshSplitL1 *)(*it))
3317 const DataArrayIdType *da=(*it)->getFamilyField();
3320 mcIdType val=da->getMaxValue(tmp);
3321 ret=std::max(ret,std::abs(val));
3328 mcIdType MEDFileUMesh::getMaxFamilyIdInArrays() const
3330 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3331 if((const DataArrayIdType *)_fam_coords)
3333 mcIdType val=_fam_coords->getMaxValue(tmp);
3334 ret=std::max(ret,val);
3336 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3338 if((const MEDFileUMeshSplitL1 *)(*it))
3340 const DataArrayIdType *da=(*it)->getFamilyField();
3343 mcIdType val=da->getMaxValue(tmp);
3344 ret=std::max(ret,val);
3351 mcIdType MEDFileUMesh::getMinFamilyIdInArrays() const
3353 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
3354 if((const DataArrayIdType *)_fam_coords)
3356 mcIdType val=_fam_coords->getMinValue(tmp);
3357 ret=std::min(ret,val);
3359 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3361 if((const MEDFileUMeshSplitL1 *)(*it))
3363 const DataArrayIdType *da=(*it)->getFamilyField();
3366 mcIdType val=da->getMinValue(tmp);
3367 ret=std::min(ret,val);
3375 * Returns the dimension on cells in \a this mesh.
3376 * \return int - the mesh dimension.
3377 * \throw If there are no cells in this mesh.
3379 int MEDFileUMesh::getMeshDimension() const
3382 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3383 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3384 return (*it)->getMeshDimension()+lev;
3385 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3389 * Returns the space dimension of \a this mesh that is equal to number of components in
3390 * the node coordinates array.
3391 * \return int - the space dimension of \a this mesh.
3392 * \throw If the node coordinates array is not available.
3394 int MEDFileUMesh::getSpaceDimension() const
3396 const DataArrayDouble *coo=_coords;
3398 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3399 return (int)coo->getNumberOfComponents();
3403 * Returns a string describing \a this mesh.
3404 * \return std::string - the mesh information string.
3406 std::string MEDFileUMesh::simpleRepr() const
3408 std::ostringstream oss;
3409 oss << MEDFileMesh::simpleRepr();
3410 const DataArrayDouble *coo=_coords;
3411 oss << "- The dimension of the space is ";
3412 static const char MSG1[]= "*** NO COORDS SET ***";
3413 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3415 oss << _coords->getNumberOfComponents() << std::endl;
3417 oss << MSG1 << std::endl;
3418 oss << "- Type of the mesh : UNSTRUCTURED\n";
3419 oss << "- Number of nodes : ";
3421 oss << _coords->getNumberOfTuples() << std::endl;
3423 oss << MSG1 << std::endl;
3424 std::size_t nbOfLev=_ms.size();
3425 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3426 for(std::size_t i=0;i<nbOfLev;i++)
3428 const MEDFileUMeshSplitL1 *lev=_ms[i];
3429 oss << " - Level #" << -((int) i) << " has dimension : ";
3432 oss << lev->getMeshDimension() << std::endl;
3433 lev->simpleRepr(oss);
3436 oss << MSG2 << std::endl;
3438 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3441 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3442 oss << "- Names of coordinates :" << std::endl;
3443 std::vector<std::string> vars=coo->getVarsOnComponent();
3444 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3445 oss << std::endl << "- Units of coordinates : " << std::endl;
3446 std::vector<std::string> units=coo->getUnitsOnComponent();
3447 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3449 oss << std::endl << std::endl;
3451 getEquivalencesRepr(oss);
3456 * Returns a full textual description of \a this mesh.
3457 * \return std::string - the string holding the mesh description.
3459 std::string MEDFileUMesh::advancedRepr() const
3461 return simpleRepr();
3465 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3466 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3467 * \return mcIdType - the number of entities.
3468 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3470 mcIdType MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3472 if(meshDimRelToMaxExt==1)
3474 if(!((const DataArrayDouble *)_coords))
3475 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3476 return _coords->getNumberOfTuples();
3478 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3482 * Returns the family field for mesh entities of a given dimension.
3483 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3484 * \return const DataArrayIdType * - the family field. It is an array of ids of families
3485 * each mesh entity belongs to. It can be \c NULL.
3487 const DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3489 if(meshDimRelToMaxExt==1)
3491 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3492 return l1->getFamilyField();
3495 DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3497 if(meshDimRelToMaxExt==1)
3499 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3500 return l1->getFamilyField();
3504 * Returns the optional numbers of mesh entities of a given dimension.
3505 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3506 * \return const DataArrayIdType * - the array of the entity numbers.
3507 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3509 const DataArrayIdType *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3511 if(meshDimRelToMaxExt==1)
3513 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3514 return l1->getNumberField();
3517 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3519 if(meshDimRelToMaxExt==1)
3520 return _name_coords;
3521 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3522 return l1->getNameField();
3525 MCAuto<DataArrayIdType> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3527 if(meshDimRelToMaxExt!=1)
3528 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3529 return _global_num_coords;
3533 * 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).
3535 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3536 * \param [in] gt - The input geometric type for which the part definition is requested.
3537 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3539 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3541 if(meshDimRelToMaxExt==1)
3542 return _part_coords;
3543 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3544 return l1->getPartDef(gt);
3547 mcIdType MEDFileUMesh::getNumberOfNodes() const
3549 const DataArrayDouble *coo(_coords);
3551 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3552 return coo->getNumberOfTuples();
3555 mcIdType MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3557 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3558 return l1->getNumberOfCells();
3561 bool MEDFileUMesh::hasImplicitPart() const
3566 mcIdType MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3568 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3571 void MEDFileUMesh::releaseImplicitPartIfAny() const
3575 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3577 std::size_t sz(st.getNumberOfItems());
3578 for(std::size_t i=0;i<sz;i++)
3580 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3581 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3582 if(st[i].getPflName().empty())
3583 m->computeNodeIdsAlg(nodesFetched);
3586 const DataArrayIdType *arr(globs->getProfile(st[i].getPflName()));
3587 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3588 m2->computeNodeIdsAlg(nodesFetched);
3593 MEDFileMesh *MEDFileUMesh::cartesianize() const
3595 if(getAxisType()==AX_CART)
3598 return const_cast<MEDFileUMesh *>(this);
3602 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3603 const DataArrayDouble *coords(_coords);
3605 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3606 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3607 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3608 if((const MEDFileUMeshSplitL1 *)(*it))
3609 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3610 ret->_coords=coordsCart;
3611 ret->setAxisType(AX_CART);
3616 bool MEDFileUMesh::presenceOfStructureElements() const
3618 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3619 if((*it).isNotNull())
3624 void MEDFileUMesh::killStructureElements()
3630 * Returns the optional numbers of mesh entities of a given dimension transformed using
3631 * DataArrayIdType::invertArrayN2O2O2N().
3632 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3633 * \return const DataArrayIdType * - the array of the entity numbers transformed using
3634 * DataArrayIdType::invertArrayN2O2O2N().
3635 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3637 const DataArrayIdType *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3639 if(meshDimRelToMaxExt==1)
3641 if(_num_coords.isNull())
3642 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3643 return _rev_num_coords;
3645 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3646 return l1->getRevNumberField();
3650 * Returns a pointer to the node coordinates array of \a this mesh \b without
3651 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3653 DataArrayDouble *MEDFileUMesh::getCoords() const
3656 MCAuto<DataArrayDouble> tmp(_coords);
3657 if((DataArrayDouble *)tmp)
3665 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3666 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3668 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3669 * \param [in] grp - the name of the group whose mesh entities are included in the
3671 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3672 * according to the optional numbers of entities, if available.
3673 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3674 * delete this mesh using decrRef() as it is no more needed.
3675 * \throw If the name of a nonexistent group is specified.
3676 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3678 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3681 synchronizeTinyInfoOnLeaves();
3682 std::vector<std::string> tmp(1);
3684 return getGroups(meshDimRelToMaxExt,tmp,renum);
3688 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3689 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3691 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3692 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3694 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3695 * according to the optional numbers of entities, if available.
3696 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3697 * delete this mesh using decrRef() as it is no more needed.
3698 * \throw If a name of a nonexistent group is present in \a grps.
3699 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3701 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3704 synchronizeTinyInfoOnLeaves();
3705 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3706 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3707 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3708 zeRet->setName(grps[0]);
3709 return zeRet.retn();
3713 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3714 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3716 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3717 * \param [in] fam - the name of the family whose mesh entities are included in the
3719 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3720 * according to the optional numbers of entities, if available.
3721 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3722 * delete this mesh using decrRef() as it is no more needed.
3723 * \throw If a name of a nonexistent family is present in \a grps.
3724 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3726 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3729 synchronizeTinyInfoOnLeaves();
3730 std::vector<std::string> tmp(1);
3732 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3736 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3737 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3739 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3740 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3742 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3743 * according to the optional numbers of entities, if available.
3744 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3745 * delete this mesh using decrRef() as it is no more needed.
3746 * \throw If a name of a nonexistent family is present in \a fams.
3747 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3749 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3752 synchronizeTinyInfoOnLeaves();
3753 if(meshDimRelToMaxExt==1)
3755 MCAuto<DataArrayIdType> arr=getFamiliesArr(1,fams,renum);
3756 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3757 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3761 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3762 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3763 MCAuto<MEDCouplingUMesh> zeRet;
3765 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3767 zeRet=l1->getFamilyPart(0,0,renum);
3768 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3769 zeRet->setName(fams[0]);
3770 return zeRet.retn();
3774 * Returns ids of mesh entities contained in given families of a given dimension.
3775 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3777 * \param [in] fams - the names of the families of interest.
3778 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3779 * returned instead of ids.
3780 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
3781 * numbers, if available and required, of mesh entities of the families. The caller
3782 * is to delete this array using decrRef() as it is no more needed.
3783 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3785 DataArrayIdType *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3787 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3788 if(meshDimRelToMaxExt==1)
3790 if(_fam_coords.isNotNull())
3792 MCAuto<DataArrayIdType> da;
3794 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3796 da=_fam_coords->findIdsEqualList(0,0);
3798 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3804 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3809 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3811 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3813 return l1->getFamilyPartArr(0,0,renum);
3817 * Returns a MEDCouplingUMesh of a given relative dimension.
3818 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3819 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3820 * To build a valid MEDCouplingUMesh from the returned one in this case,
3821 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3822 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3823 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3824 * optional numbers of mesh entities.
3825 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3826 * delete using decrRef() as it is no more needed.
3827 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3829 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3832 synchronizeTinyInfoOnLeaves();
3833 if(meshDimRelToMaxExt==1)
3837 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3838 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3839 umesh->setCoords(cc);
3840 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3841 umesh->setName(getName());
3845 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3846 return l1->getWholeMesh(renum);
3849 std::vector<mcIdType> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3851 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3852 return l1->getDistributionOfTypes();
3856 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3857 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3858 * optional numbers of mesh entities.
3859 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3860 * delete using decrRef() as it is no more needed.
3861 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3863 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3865 return getMeshAtLevel(0,renum);
3869 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3870 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3871 * optional numbers of mesh entities.
3872 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3873 * delete using decrRef() as it is no more needed.
3874 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3876 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3878 return getMeshAtLevel(-1,renum);
3882 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3883 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3884 * optional numbers of mesh entities.
3885 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3886 * delete using decrRef() as it is no more needed.
3887 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3889 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3891 return getMeshAtLevel(-2,renum);
3895 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3896 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3897 * optional numbers of mesh entities.
3898 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3899 * delete using decrRef() as it is no more needed.
3900 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3902 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3904 return getMeshAtLevel(-3,renum);
3908 * This method inform datastructure that vector of MEDCoupling1GTUMesh instances have been touched.
3909 * So the version of data to take is vector of MEDCoupling1GTUMesh not MEDCouplingUMesh
3911 void MEDFileUMesh::declarePartsUpdated() const
3913 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3915 const MEDFileUMeshSplitL1 *elt(*it);
3917 elt->declarePartsUpdated();
3922 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3923 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3924 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3925 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3927 * \sa MEDFileUMesh::declarePartsUpdated
3929 void MEDFileUMesh::forceComputationOfParts() const
3931 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3933 const MEDFileUMeshSplitL1 *elt(*it);
3935 elt->forceComputationOfParts();
3940 * This method returns a vector of mesh parts containing each exactly one geometric type.
3941 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3942 * This method is only for memory aware users.
3943 * The returned pointers are **NOT** new object pointer. No need to mange them.
3945 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3948 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3949 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3953 * This method returns the part of \a this having the geometric type \a gt.
3954 * If such part is not existing an exception will be thrown.
3955 * The returned pointer is **NOT** new object pointer. No need to mange it.
3957 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3960 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3961 int lev=(int)cm.getDimension()-getMeshDimension();
3962 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3963 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3967 * This method returns for each geo types in \a this number of cells with this geo type.
3968 * 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.
3969 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3971 * \sa getDistributionOfTypes
3973 std::vector< std::pair<int,mcIdType> > MEDFileUMesh::getAllDistributionOfTypes() const
3975 std::vector< std::pair<int,mcIdType> > ret;
3976 std::vector<int> nel(getNonEmptyLevels());
3977 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3979 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3980 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3982 mcIdType nbCells(getNumberOfCellsWithType(*it1));
3983 ret.push_back(std::pair<int,mcIdType>(*it1,nbCells));
3986 ret.push_back(std::pair<int,mcIdType>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3991 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3992 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3994 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3996 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3997 return sp->getGeoTypes();
4000 mcIdType MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
4002 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
4003 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
4004 return sp->getNumberOfCellsWithType(ct);
4008 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
4009 * \param [in] gt - the geometric type for which the family field is asked.
4010 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
4011 * delete using decrRef() as it is no more needed.
4012 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
4014 DataArrayIdType *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
4016 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
4017 int lev=(int)cm.getDimension()-getMeshDimension();
4018 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
4019 return sp->extractFamilyFieldOnGeoType(gt);
4023 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
4024 * \param [in] gt - the geometric type for which the number field is asked.
4025 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
4026 * delete using decrRef() as it is no more needed.
4027 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
4029 DataArrayIdType *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
4031 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
4032 int lev=(int)cm.getDimension()-getMeshDimension();
4033 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
4034 return sp->extractNumberFieldOnGeoType(gt);
4038 * This method returns for specified geometric type \a gt the relative level to \a this.
4039 * If the relative level is empty an exception will be thrown.
4041 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
4043 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
4044 int ret((int)cm.getDimension()-getMeshDimension());
4045 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
4049 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
4051 if(meshDimRelToMaxExt==1)
4052 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
4053 if(meshDimRelToMaxExt>1)
4054 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
4055 int tracucedRk=-meshDimRelToMaxExt;
4056 if(tracucedRk>=(int)_ms.size())
4057 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4058 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
4059 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4060 return _ms[tracucedRk];
4063 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
4065 if(meshDimRelToMaxExt==1)
4066 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
4067 if(meshDimRelToMaxExt>1)
4068 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
4069 int tracucedRk=-meshDimRelToMaxExt;
4070 if(tracucedRk>=(int)_ms.size())
4071 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4072 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
4073 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4074 return _ms[tracucedRk];
4077 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
4079 if(-meshDimRelToMax>=(int)_ms.size())
4080 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
4082 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
4084 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
4086 int ref=(*it)->getMeshDimension();
4087 if(ref+i!=meshDim-meshDimRelToMax)
4088 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
4094 * Sets the node coordinates array of \a this mesh.
4095 * \param [in] coords - the new node coordinates array.
4096 * \throw If \a coords == \c NULL.
4098 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
4101 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
4102 if(coords==(DataArrayDouble *)_coords)
4104 coords->checkAllocated();
4105 mcIdType nbOfTuples(coords->getNumberOfTuples());
4106 _coords.takeRef(coords);
4107 _fam_coords=DataArrayIdType::New();
4108 _fam_coords->alloc(nbOfTuples,1);
4109 _fam_coords->fillWithZero();
4110 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
4111 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4112 if((MEDFileUMeshSplitL1 *)(*it))
4113 (*it)->setCoords(coords);
4117 * Change coords without changing anything concerning families and numbering on nodes.
4119 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
4122 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
4123 if(coords==(DataArrayDouble *)_coords)
4125 coords->checkAllocated();
4126 mcIdType nbOfTuples(coords->getNumberOfTuples());
4127 if(_coords.isNull())
4134 mcIdType oldNbTuples(_coords->getNumberOfTuples());
4135 if(oldNbTuples!=nbOfTuples)
4136 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
4140 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4141 if((MEDFileUMeshSplitL1 *)(*it))
4142 (*it)->setCoords(coords);
4146 * Removes all groups of a given dimension in \a this mesh.
4147 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4148 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4150 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
4152 if(meshDimRelToMaxExt==1)
4154 if((DataArrayIdType *)_fam_coords)
4155 _fam_coords->fillWithZero();
4158 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
4159 l1->eraseFamilyField();
4164 * Removes all families with ids not present in the family fields of \a this mesh.
4166 void MEDFileUMesh::optimizeFamilies()
4168 std::vector<int> levs=getNonEmptyLevelsExt();
4169 std::set<mcIdType> allFamsIds;
4170 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4172 const DataArrayIdType *ffield=getFamilyFieldAtLevel(*it);
4173 MCAuto<DataArrayIdType> ids=ffield->getDifferentValues();
4174 std::set<mcIdType> res;
4175 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
4178 std::set<std::string> famNamesToKill;
4179 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
4181 if(allFamsIds.find((*it).second)!=allFamsIds.end())
4182 famNamesToKill.insert((*it).first);
4184 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
4185 _families.erase(*it);
4186 std::vector<std::string> grpNamesToKill;
4187 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
4189 std::vector<std::string> tmp;
4190 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
4192 if(famNamesToKill.find(*it2)==famNamesToKill.end())
4193 tmp.push_back(*it2);
4198 tmp.push_back((*it).first);
4200 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
4205 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
4206 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
4207 * The boundary is built according to the following method:
4208 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
4209 * coordinates array is extended).
4210 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
4211 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
4212 * might not be duplicated at all.
4213 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
4214 * other side of the group is no more a neighbor)
4215 * - the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
4216 * bordering the newly created boundary use the newly computed nodes.
4217 * - finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
4218 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
4220 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
4221 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
4223 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
4224 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
4225 * \sa clearNodeAndCellNumbers()
4227 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayIdType *&nodesDuplicated,
4228 DataArrayIdType *&cellsModified, DataArrayIdType *&cellsNotModified)
4230 typedef MCAuto<MEDCouplingUMesh> MUMesh;
4231 typedef MCAuto<DataArrayIdType> DAInt;
4233 std::vector<int> levs=getNonEmptyLevels();
4234 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
4235 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
4236 MUMesh m0=getMeshAtLevel(0);
4237 MUMesh m1=getMeshAtLevel(-1);
4238 mcIdType nbNodes=m0->getNumberOfNodes();
4239 MUMesh m11=getGroup(-1,grpNameM1);
4240 DataArrayIdType *tmp00=0, *tmp11=0,*tmp22=0;
4242 // !!! The core of the duplication logic is in these 2 methods:
4244 DAInt nodeIdsToDuplicate = m0->findNodesToDuplicate(*m11); // identify nodes to duplicate
4245 m0->findCellsToRenumber(*m11, nodeIdsToDuplicate->begin(), nodeIdsToDuplicate->end(), tmp11,tmp22); // identify cells needing renumbering
4246 DAInt cellsToModifyConn0(tmp11);
4247 DAInt cellsToModifyConn1(tmp22);
4250 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4251 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4252 DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New();
4253 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4254 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4255 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4256 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4257 DataArrayIdType *cellsInM1ToRenumW4Tmp=0;
4258 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4259 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4260 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4261 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4262 DAInt grpIds=getGroupArr(-1,grpNameM1);
4263 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4264 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4265 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4266 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4267 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4268 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4269 m0->setCoords(tmp0->getCoords());
4270 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4271 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4272 m1->setCoords(m0->getCoords());
4273 _coords=m0->getCoords(); _coords->incrRef();
4274 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4275 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4276 DataArrayIdType * duplCells;
4277 m1->areCellsIncludedIn(m11, 0, duplCells);
4278 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4279 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4280 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4281 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4282 DAInt szOfCellGrpOfSameType(tmp00);
4283 DAInt idInMsOfCellGrpOfSameType(tmp11);
4285 newm1->setName(getName());
4286 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
4288 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4289 DAInt newFam=DataArrayIdType::New();
4290 newFam->alloc(newm1->getNumberOfCells(),1);
4291 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4292 // Positive ID for family of nodes, negative for all the rest.
4294 if (m1->getMeshDimension() == 0)
4295 idd=getMaxFamilyId()+1;
4297 idd=getMinFamilyId()-1;
4298 mcIdType globStart=0,start=0,end,globEnd;
4299 mcIdType nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4300 for(mcIdType i=0;i<nbOfChunks;i++)
4302 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4303 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4305 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4306 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4307 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4312 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4316 newm1->setCoords(getCoords());
4317 setMeshAtLevel(-1,newm1);
4318 setFamilyFieldArr(-1,newFam);
4319 std::string grpName2(grpNameM1); grpName2+="_dup";
4320 addFamily(grpName2,idd);
4321 addFamilyOnGrp(grpName2,grpName2);
4326 mcIdType newNbOfNodes=getCoords()->getNumberOfTuples();
4327 newFam=DataArrayIdType::New(); newFam->alloc(newNbOfNodes,1);
4328 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4329 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4333 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4335 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4336 it != _ms.end(); it++)
4339 (*it)->_rev_num = 0;
4341 nodesDuplicated=nodeIdsToDuplicate.retn();
4342 cellsModified=cellsToModifyConn0.retn();
4343 cellsNotModified=cellsToModifyConn1.retn();
4346 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4347 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4350 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4351 * \param [out] newCode retrieves the distribution of types after the call if true is returned
4352 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4354 * \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.
4355 * 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.
4357 bool MEDFileUMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
4359 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4360 std::vector<int> levs=getNonEmptyLevels();
4362 std::vector< const DataArrayIdType* > renumCellsSplited;//same than memorySaverIfThrow
4363 std::vector< MCAuto<DataArrayIdType> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4366 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4368 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4369 std::vector<mcIdType> code1=m->getDistributionOfTypes();
4370 end=PutInThirdComponentOfCodeOffset(code1,start);
4371 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4372 bool hasChanged=m->unPolyze();
4373 DataArrayIdType *fake=0;
4374 MCAuto<DataArrayIdType> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4375 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4377 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4380 MCAuto<DataArrayIdType> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4381 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4383 MCAuto<DataArrayIdType> famField2,numField2;
4384 const DataArrayIdType *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayIdType *>(famField); }
4385 const DataArrayIdType *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayIdType *>(numField); }
4386 setMeshAtLevel(*it,m);
4387 std::vector<mcIdType> code2=m->getDistributionOfTypes();
4388 end=PutInThirdComponentOfCodeOffset(code2,start);
4389 newCode.insert(newCode.end(),code2.begin(),code2.end());
4391 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4395 MCAuto<DataArrayIdType> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4396 setFamilyFieldArr(*it,newFamField);
4400 MCAuto<DataArrayIdType> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4401 setRenumFieldArr(*it,newNumField);
4406 newCode.insert(newCode.end(),code1.begin(),code1.end());
4412 MCAuto<DataArrayIdType> renumCells=DataArrayIdType::Aggregate(renumCellsSplited);
4413 MCAuto<DataArrayIdType> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4414 o2nRenumCell=o2nRenumCellRet.retn();
4419 /*! \cond HIDDEN_ITEMS */
4420 struct MEDLoaderAccVisit1
4422 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4423 mcIdType operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4424 mcIdType _new_nb_of_nodes;
4429 * 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.
4430 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4431 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4432 * -1 values in returned array means that the corresponding old node is no more used.
4434 * \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
4435 * is modified in \a this.
4436 * \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
4439 DataArrayIdType *MEDFileUMesh::zipCoords()
4441 const DataArrayDouble *coo(getCoords());
4443 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4444 mcIdType nbOfNodes(coo->getNumberOfTuples());
4445 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4446 std::vector<int> neLevs(getNonEmptyLevels());
4447 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4449 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4450 if(zeLev->isMeshStoredSplitByType())
4452 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4453 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4455 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4459 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4460 mesh->computeNodeIdsAlg(nodeIdsInUse);
4463 mcIdType nbrOfNodesInUse((mcIdType)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4464 if(nbrOfNodesInUse==nbOfNodes)
4465 return 0;//no need to update _part_coords
4466 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfNodes,1);
4467 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4468 MCAuto<DataArrayIdType> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4469 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4470 MCAuto<DataArrayIdType> newFamCoords;
4471 MCAuto<DataArrayAsciiChar> newNameCoords;
4472 if((const DataArrayIdType *)_fam_coords)
4473 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4474 MCAuto<DataArrayIdType> newNumCoords,newGlobalNumCoords;
4475 if(_num_coords.isNotNull())
4476 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4477 if(_global_num_coords.isNotNull())
4478 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4479 if(_name_coords.isNotNull())
4480 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4481 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4482 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4484 if((MEDFileUMeshSplitL1*)*it)
4486 (*it)->renumberNodesInConn(ret->begin());
4487 (*it)->setCoords(_coords);
4490 // updates _part_coords
4491 const PartDefinition *pc(_part_coords);
4494 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4495 _part_coords=tmpPD->composeWith(pc);
4501 * This method is the extension of MEDCouplingUMesh::computeFetchedNodeIds. Except that here all levels are considered here.
4503 * \return newly allocated array containing all nodes in \a this that are part of nodal connectivity of at least one cell in \a this whatever its level.
4505 DataArrayIdType *MEDFileUMesh::computeFetchedNodeIds() const
4507 std::vector<int> neLevs(this->getNonEmptyLevels());
4508 std::vector<bool> nodesHighlighted(this->getNumberOfNodes(),false);
4509 for(auto lev : neLevs)
4511 const MEDFileUMeshSplitL1 *zeLev(this->getMeshAtLevSafe(lev));
4512 zeLev->highlightUsedNodes(nodesHighlighted);
4514 return DataArrayIdType::BuildListOfSwitchedOn(nodesHighlighted);
4518 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4519 * The extraction of \a this is specified by the extractDef \a input map.
4520 * This map tells for each level of cells, the cells kept in the extraction.
4522 * \return - a new reference of DataArrayIdType that represents sorted node ids, the extraction is lying on.
4523 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4525 DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4527 std::vector<int> levs(getNonEmptyLevels());
4528 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4529 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4532 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4533 if((*it).second.isNull())
4534 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4537 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4539 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4540 throw INTERP_KERNEL::Exception(oss.str());
4542 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4543 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4544 mPart->computeNodeIdsAlg(fetchedNodes);
4546 return DataArrayIdType::BuildListOfSwitchedOn(fetchedNodes);
4550 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4552 * \return - a new reference of MEDFileUMesh
4553 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart, MEDFileUMesh.reduceToCells
4555 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4557 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4558 std::vector<int> levs(getNonEmptyLevels());
4559 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4562 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4563 if((*it).second.isNull())
4564 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4567 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4569 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4570 throw INTERP_KERNEL::Exception(oss.str());
4572 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4573 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4574 ret->setMeshAtLevel((*it).first,mPart);
4575 const DataArrayIdType *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4578 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4579 ret->setFamilyFieldArr((*it).first,famPart);
4583 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4584 ret->setFamilyFieldArr((*it).first,numPart);
4587 std::map<int, MCAuto<DataArrayIdType> >::const_iterator it2(extractDef.find(1));
4588 if(it2!=extractDef.end())
4590 const DataArrayDouble *coo(ret->getCoords());
4592 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4593 MCAuto<DataArrayIdType> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4594 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4595 ret->setCoords(cooPart);
4596 const DataArrayIdType *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4599 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4600 ret->setFamilyFieldArr(1,famPart);
4604 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4605 ret->setFamilyFieldArr(1,numPart);
4607 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4611 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4612 m->renumberNodesInConn(o2nNodes->begin());
4613 ret->setMeshAtLevel((*it3).first,m);
4620 * This method performs an extrusion along a path defined by \a m1D.
4621 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4622 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4623 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4624 * This method scans all levels in \a this
4625 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4627 * \param [in] m1D - the mesh defining the extrusion path.
4628 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4629 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4631 * \sa MEDCouplingUMesh::buildExtrudedMesh
4633 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4636 if(getMeshDimension()!=2)
4637 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4638 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4639 m1D->checkConsistencyLight();
4640 if(m1D->getMeshDimension()!=1)
4641 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4642 mcIdType nbRep(m1D->getNumberOfCells());
4643 std::vector<int> levs(getNonEmptyLevels());
4644 std::vector<std::string> grps(getGroupsNames());
4645 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4646 DataArrayDouble *coords(0);
4647 std::size_t nbOfLevsOut(levs.size()+1);
4648 std::vector< MCAuto<DataArrayIdType> > o2ns(nbOfLevsOut);
4649 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4651 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4652 item=item->clone(false);
4653 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4654 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4655 tmp->changeSpaceDimension(3+(*lev),0.);
4656 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4657 zeList.push_back(elt);
4659 coords=elt->getCoords();
4662 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4663 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4665 (*it)->setName(getName());
4666 (*it)->setCoords(coords);
4668 for(std::size_t ii=0;ii!=zeList.size();ii++)
4671 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4674 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4675 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4676 MCAuto<DataArrayIdType> tmp(elt2->getNodalConnectivity()->deepCopy());
4677 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4678 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4679 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4680 std::vector<const MEDCouplingUMesh *> elts(3);
4681 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4682 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4683 elt->setName(getName());
4686 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4687 ret->setMeshAtLevel(lev,elt);
4689 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4690 endLev=endLev->clone(false); endLev->setCoords(coords);
4691 MCAuto<DataArrayIdType> tmp(endLev->getNodalConnectivity()->deepCopy());
4692 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4693 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4694 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4695 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4696 endLev->setName(getName());
4697 ret->setMeshAtLevel(levs.back()-1,endLev);
4699 for(std::size_t ii=0;ii!=zeList.size();ii++)
4702 std::vector< MCAuto<DataArrayIdType> > outGrps;
4703 std::vector< const DataArrayIdType * > outGrps2;
4706 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4708 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev+1,*grp));
4709 if(!grpArr->empty())
4711 MCAuto<DataArrayIdType> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4712 mcIdType offset0(zeList[ii]->getNumberOfCells());
4713 mcIdType offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4714 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4715 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4716 grpArr2->setName(oss.str());
4717 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4718 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4719 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4720 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4725 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4727 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev,*grp));
4728 if(!grpArr->empty())
4730 mcIdType nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4731 std::vector< MCAuto<DataArrayIdType> > grpArrs(nbRep);
4732 std::vector< const DataArrayIdType *> grpArrs2(nbRep);
4733 for(int iii=0;iii<nbRep;iii++)
4735 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4736 grpArrs2[iii]=grpArrs[iii];
4738 MCAuto<DataArrayIdType> grpArrExt(DataArrayIdType::Aggregate(grpArrs2));
4739 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4740 std::ostringstream grpName; grpName << *grp << "_extruded";
4741 grpArrExt->setName(grpName.str());
4742 outGrps.push_back(grpArrExt);
4743 outGrps2.push_back(grpArrExt);
4746 ret->setGroupsAtLevel(lev,outGrps2);
4748 std::vector< MCAuto<DataArrayIdType> > outGrps;
4749 std::vector< const DataArrayIdType * > outGrps2;
4750 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4752 MCAuto<DataArrayIdType> grpArr1(getGroupArr(levs.back(),*grp));
4753 if(grpArr1->empty())
4755 MCAuto<DataArrayIdType> grpArr2(grpArr1->deepCopy());
4756 std::ostringstream grpName; grpName << *grp << "_top";
4757 grpArr2->setName(grpName.str());
4758 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4759 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4760 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4762 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4767 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4768 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4769 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4771 * \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
4772 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4773 * \param [in] eps - detection threshold for coordinates.
4774 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4776 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4778 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4781 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4782 mcIdType initialNbNodes(getNumberOfNodes());
4783 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4784 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4786 MCAuto<DataArrayIdType> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4788 DataArrayDouble *zeCoords(m0->getCoords());
4789 ret->setMeshAtLevel(0,m0);
4790 std::vector<int> levs(getNonEmptyLevels());
4791 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4794 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4795 ret->setFamilyFieldArr(0,famFieldCpy);
4797 famField=getFamilyFieldAtLevel(1);
4800 MCAuto<DataArrayIdType> fam(DataArrayIdType::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4801 fam->fillWithZero();
4802 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4803 ret->setFamilyFieldArr(1,fam);
4805 ret->copyFamGrpMapsFrom(*this);
4806 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4807 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4811 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4812 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4813 if(m1->getMeshDimension()!=0)
4816 MCAuto<DataArrayIdType> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4817 }//kill unused notUsed var
4818 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4819 DataArrayIdType *b(0);
4820 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4821 MCAuto<DataArrayIdType> bSafe(b);
4824 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4825 throw INTERP_KERNEL::Exception(oss.str().c_str());
4827 b->applyLin(1,initialNbNodes);
4828 MCAuto<DataArrayIdType> l0(DataArrayIdType::New()); l0->alloc(initialNbNodes,1); l0->iota();
4829 std::vector<const DataArrayIdType *> v(2); v[0]=l0; v[1]=b;
4830 MCAuto<DataArrayIdType> renum(DataArrayIdType::Aggregate(v));
4831 m1->renumberNodesInConn(renum->begin());
4833 m1->setCoords(zeCoords);
4834 ret->setMeshAtLevel(*lev,m1);
4835 famField=getFamilyFieldAtLevel(*lev);
4838 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4839 ret->setFamilyFieldArr(*lev,famFieldCpy);
4846 * This method converts all quadratic cells in \a this into linear cells.
4847 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4848 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4850 * \param [in] eps - detection threshold for coordinates.
4851 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4853 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4855 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4858 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4859 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4860 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4861 m0->convertQuadraticCellsToLinear();
4863 DataArrayDouble *zeCoords(m0->getCoords());
4864 ret->setMeshAtLevel(0,m0);
4865 std::vector<int> levs(getNonEmptyLevels());
4866 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4869 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4870 ret->setFamilyFieldArr(0,famFieldCpy);
4872 famField=getFamilyFieldAtLevel(1);
4875 MCAuto<DataArrayIdType> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4876 ret->setFamilyFieldArr(1,fam);
4878 ret->copyFamGrpMapsFrom(*this);
4879 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4883 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4884 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4885 m1->convertQuadraticCellsToLinear();
4887 DataArrayIdType *b(0);
4888 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4889 MCAuto<DataArrayIdType> bSafe(b);
4892 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4893 throw INTERP_KERNEL::Exception(oss.str().c_str());
4895 m1->renumberNodesInConn(b->begin());
4896 m1->setCoords(zeCoords);
4897 ret->setMeshAtLevel(*lev,m1);
4898 famField=getFamilyFieldAtLevel(*lev);
4901 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4902 ret->setFamilyFieldArr(*lev,famFieldCpy);
4909 * Computes the symmetry of \a this.
4910 * \return a new object.
4912 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4914 MCAuto<MEDFileUMesh> ret(deepCopy());
4915 DataArrayDouble *myCoo(getCoords());
4918 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4919 ret->setCoordsForced(newCoo);
4925 * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
4926 * merged in such a way that the final mesh contain all of them.
4927 * \return a new object.
4929 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4932 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4933 std::size_t sz(meshes.size()),i(0);
4934 std::vector<const DataArrayDouble *> coos(sz);
4935 std::vector<const DataArrayIdType *> fam_coos(sz),num_coos(sz);
4936 for(auto it=meshes.begin();it!=meshes.end();it++,i++)
4939 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4940 coos[i]=(*it)->getCoords();
4941 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4942 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4944 const MEDFileUMesh *ref(meshes[0]);
4945 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4946 std::vector<int> levs(ref->getNonEmptyLevels());
4947 std::map<int, std::vector<const DataArrayIdType *> > m_fam,m_renum;
4948 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4949 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4950 std::map<std::string,mcIdType> famNumMap;
4951 std::map<mcIdType, std::string> famNumMap_rev;
4952 std::map<std::string, std::vector<std::string> > grpFamMap;
4953 std::set< MCAuto<DataArrayIdType> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
4955 // Identify min family number used:
4956 mcIdType min_fam_num(0);
4957 for(const auto& msh : meshes)
4959 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4960 for(const auto& it3 : locMap1)
4961 if(it3.second < min_fam_num)
4962 min_fam_num = it3.second;
4965 for(const auto& msh : meshes)
4967 if(msh->getSpaceDimension()!=spaceDim)
4968 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4969 if(msh->getMeshDimension()!=meshDim)
4970 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4971 if(msh->getNonEmptyLevels()!=levs)
4972 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4974 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4975 std::map<std::string, std::string> substitute;
4976 std::map<mcIdType, mcIdType> substituteN;
4977 bool fam_conflict(false);
4978 for(const auto& it3 : locMap1)
4980 const std::string& famName = it3.first;
4981 mcIdType famNum = it3.second;
4982 if (famNumMap_rev.count(famNum) || famNumMap.count(famName)) // Family number, or family name is already used!
4984 bool needsRenum = true;
4985 // Algorithm is as follows: if couple (name, id) do **not** match with the previously registered name and id,
4986 // then current family is declared as needing renumbering (needsRenum=True) to avoid strange situations.
4987 // Otherwise we just trigger a renum if the family is used by a group (either in the current mesh, or in a previous one).
4988 // Thus, if not used by any group at all (but consistent!!), this is actually OK, we can just merge this family by aggregating (typically -1 familly).
4990 // 1. ID and name matching ?
4991 if (famNumMap_rev.count(famNum) && famNumMap_rev.at(famNum) == famName &&
4992 famNumMap.count(famName) && famNumMap.at(famName) == famNum)
4998 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4999 for(const auto& it4 : locMap2)
5001 const auto& famLst = it4.second;
5002 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
5003 { needsRenum = true; break; }
5006 // 3. Previous meshes ...
5008 for(const auto& it4 : grpFamMap)
5010 const auto& famLst = it4.second;
5011 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
5012 { needsRenum = true; break; }
5016 { // Generate a new family name, and a new family number
5017 fam_conflict = true;
5018 std::ostringstream oss;
5019 oss << "Family_" << --min_fam_num; // New ID
5020 std::string new_name(oss.str());
5021 substitute[famName] = new_name;
5022 substituteN[famNum] = min_fam_num;
5023 famNumMap[new_name] = min_fam_num;
5024 famNumMap_rev[min_fam_num] = new_name;
5029 famNumMap[famName] = famNum;
5030 famNumMap_rev[famNum] = famName;
5034 for(const auto& level : levs)
5036 MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
5037 m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
5038 m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
5040 // Family field - substitute new family number if needed:
5043 DataArrayIdType* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
5044 mem_cleanup.insert(MCAuto<DataArrayIdType>(dai)); // Make sure array will decrRef() at end of method
5045 for (const auto& subN : substituteN)
5046 dai->changeValue(subN.first, subN.second);
5047 m_fam[level].push_back(dai);
5050 m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
5053 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
5054 for(const auto& grpItem : locMap2)
5056 const std::string& grpName = grpItem.first;
5057 std::vector<std::string> famLst;
5058 // Substitute family name in group description if needed:
5061 famLst = grpItem.second;
5062 for (const auto& sub : substitute)
5063 std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
5066 famLst = grpItem.second;
5068 // Potentially merge groups (if same name):
5069 const auto& it = grpFamMap.find(grpName);
5070 if (it != grpFamMap.end())
5072 // Group already exists, merge should be done. Normally we whould never
5073 // have twice the same family name in famLstCur and famLst since we dealt with family number
5074 // conflict just above ...
5075 std::vector<std::string>& famLstCur = (*it).second;
5076 famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
5079 grpFamMap[grpName] = famLst;
5082 // Easy part : nodes
5083 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
5084 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
5085 ret->setCoords(coo);
5086 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayIdType *)0)==fam_coos.end())
5088 MCAuto<DataArrayIdType> fam_coo(DataArrayIdType::Aggregate(fam_coos));
5089 ret->setFamilyFieldArr(1,fam_coo);
5091 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayIdType *)0)==num_coos.end())
5093 MCAuto<DataArrayIdType> num_coo(DataArrayIdType::Aggregate(num_coos));
5094 ret->setRenumFieldArr(1,num_coo);
5097 for(const auto& level : levs)
5099 auto it2(m_mesh.find(level));
5100 if(it2==m_mesh.end())
5101 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
5102 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
5103 mesh->setCoords(coo); mesh->setName(ref->getName());
5104 MCAuto<DataArrayIdType> renum(mesh->sortCellsInMEDFileFrmt());
5105 ret->setMeshAtLevel(level,mesh);
5106 auto it3(m_fam.find(level)),it4(m_renum.find(level));
5107 if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
5108 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
5109 if(it4==m_renum.end())
5110 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
5111 // Set new family field if it was defined for all input meshes
5112 const std::vector<const DataArrayIdType *>& fams((*it3).second);
5113 if(std::find(fams.begin(),fams.end(),(const DataArrayIdType *)0)==fams.end())
5115 MCAuto<DataArrayIdType> famm(DataArrayIdType::Aggregate(fams));
5116 famm->renumberInPlace(renum->begin());
5117 ret->setFamilyFieldArr(level,famm);
5119 // Set optional number field if defined for all input meshes:
5120 const std::vector<const DataArrayIdType *>& renums((*it4).second);
5121 if(std::find(renums.begin(),renums.end(),(const DataArrayIdType *)0)==renums.end())
5123 MCAuto<DataArrayIdType> renumm(DataArrayIdType::Aggregate(renums));
5124 renumm->renumberInPlace(renum->begin());
5125 ret->setRenumFieldArr(level,renumm);
5129 ret->setFamilyInfo(famNumMap);
5130 ret->setGroupInfo(grpFamMap);
5131 ret->setName(ref->getName());
5135 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
5137 if(getMeshDimension()!=3)
5138 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
5139 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
5140 if(m3D.isNull() || m2D.isNull())
5141 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
5142 mcIdType zeId(std::numeric_limits<med_int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
5143 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
5147 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5149 clearNonDiscrAttributes();
5150 forceComputationOfParts();
5151 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
5152 std::vector<mcIdType> layer0;
5153 layer0.push_back(getAxisType());//0 i
5154 layer0.push_back(_order); //1 i
5155 layer0.push_back(_iteration);//2 i
5156 layer0.push_back(getSpaceDimension());//3 i
5157 tinyDouble.push_back(_time);//0 d
5158 tinyStr.push_back(_name);//0 s
5159 tinyStr.push_back(_desc_name);//1 s
5160 for(int i=0;i<getSpaceDimension();i++)
5161 tinyStr.push_back(_coords->getInfoOnComponent(i));
5162 layer0.push_back(ToIdType(_families.size()));//4 i <- key info aa layer#0
5163 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
5165 tinyStr.push_back((*it).first);
5166 layer0.push_back((*it).second);
5168 layer0.push_back((mcIdType)_groups.size());//4+aa i <- key info bb layer#0
5169 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
5171 layer0.push_back(ToIdType((*it0).second.size()));
5172 tinyStr.push_back((*it0).first);
5173 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
5174 tinyStr.push_back(*it1);
5176 // sizeof(layer0)==4+aa+1+bb layer#0
5177 bigArrayD=_coords;// 0 bd
5178 bigArraysI.push_back(_fam_coords);// 0 bi
5179 bigArraysI.push_back(_num_coords);// 1 bi
5180 const PartDefinition *pd(_part_coords);
5182 layer0.push_back(-1);
5185 std::vector<mcIdType> tmp0;
5186 pd->serialize(tmp0,bigArraysI);
5187 tinyInt.push_back(ToIdType(tmp0.size()));
5188 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
5191 std::vector<mcIdType> layer1;
5192 std::vector<int> levs(getNonEmptyLevels());
5193 layer1.push_back((mcIdType)levs.size());// 0 i <- key
5194 layer1.insert(layer1.end(),levs.begin(),levs.end());
5195 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
5197 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
5198 lev->serialize(layer1,bigArraysI);
5200 // put layers all together.
5201 tinyInt.push_back(ToIdType(layer0.size()));
5202 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
5203 tinyInt.push_back(ToIdType(layer1.size()));
5204 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
5207 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr,
5208 std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5210 mcIdType sz0(tinyInt[0]);
5211 std::vector<mcIdType> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
5212 mcIdType sz1(tinyInt[sz0+1]);
5213 std::vector<mcIdType> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
5215 std::reverse(layer0.begin(),layer0.end());
5216 std::reverse(layer1.begin(),layer1.end());
5217 std::reverse(tinyDouble.begin(),tinyDouble.end());
5218 std::reverse(tinyStr.begin(),tinyStr.end());
5219 std::reverse(bigArraysI.begin(),bigArraysI.end());
5221 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
5222 _order=FromIdType<int>(layer0.back()); layer0.pop_back();
5223 _iteration=FromIdType<int>(layer0.back()); layer0.pop_back();
5224 mcIdType spaceDim(layer0.back()); layer0.pop_back();
5225 _time=tinyDouble.back(); tinyDouble.pop_back();
5226 _name=tinyStr.back(); tinyStr.pop_back();
5227 _desc_name=tinyStr.back(); tinyStr.pop_back();
5228 _coords=bigArrayD; _coords->rearrange(spaceDim);
5229 for(int i=0;i<spaceDim;i++)
5231 _coords->setInfoOnComponent(i,tinyStr.back());
5234 mcIdType nbOfFams(layer0.back()); layer0.pop_back();
5236 for(mcIdType i=0;i<nbOfFams;i++)
5238 _families[tinyStr.back()]=layer0.back();
5239 tinyStr.pop_back(); layer0.pop_back();
5241 mcIdType nbGroups(layer0.back()); layer0.pop_back();
5243 for(mcIdType i=0;i<nbGroups;i++)
5245 std::string grpName(tinyStr.back()); tinyStr.pop_back();
5246 mcIdType nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
5247 std::vector<std::string> fams(nbOfFamsOnGrp);
5248 for(mcIdType j=0;j<nbOfFamsOnGrp;j++)
5250 fams[j]=tinyStr.back(); tinyStr.pop_back();
5252 _groups[grpName]=fams;
5254 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
5255 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
5257 mcIdType isPd(layer0.back()); layer0.pop_back();
5260 std::vector<mcIdType> tmp0(layer0.begin(),layer0.begin()+isPd);
5261 layer0.erase(layer0.begin(),layer0.begin()+isPd);
5262 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
5265 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
5267 mcIdType nbLevs(layer1.back()); layer1.pop_back();
5268 std::vector<mcIdType> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
5270 mcIdType maxLev(-(*std::min_element(levs.begin(),levs.end())));
5271 _ms.resize(maxLev+1);
5272 for(mcIdType i=0;i<nbLevs;i++)
5274 mcIdType lev(levs[i]);
5276 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
5281 * Adds a group of nodes to \a this mesh.
5282 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5283 * The ids should be sorted and different each other (MED file norm).
5285 * \warning this method can alter default "FAMILLE_ZERO" family.
5286 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5288 * \throw If the node coordinates array is not set.
5289 * \throw If \a ids == \c NULL.
5290 * \throw If \a ids->getName() == "".
5291 * \throw If \a ids does not respect the MED file norm.
5292 * \throw If a group with name \a ids->getName() already exists.
5294 void MEDFileUMesh::addNodeGroup(const DataArrayIdType *ids)
5296 const DataArrayDouble *coords(_coords);
5298 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
5299 mcIdType nbOfNodes(coords->getNumberOfTuples());
5300 if(_fam_coords.isNull())
5301 { _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
5303 addGroupUnderground(true,ids,_fam_coords);
5307 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5309 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5310 * The ids should be sorted and different each other (MED file norm).
5312 * \warning this method can alter default "FAMILLE_ZERO" family.
5313 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5315 * \throw If the node coordinates array is not set.
5316 * \throw If \a ids == \c NULL.
5317 * \throw If \a ids->getName() == "".
5318 * \throw If \a ids does not respect the MED file norm.
5319 * \throw If a group with name \a ids->getName() already exists.
5321 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
5323 std::vector<int> levs(getNonEmptyLevelsExt());
5324 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
5326 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
5327 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
5329 if(meshDimRelToMaxExt==1)
5330 { addNodeGroup(ids); return ; }
5331 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
5332 DataArrayIdType *fam(lev->getOrCreateAndGetFamilyField());
5333 addGroupUnderground(false,ids,fam);
5337 * Changes a name of a family specified by its id.
5338 * \param [in] id - the id of the family of interest.
5339 * \param [in] newFamName - the new family name.
5340 * \throw If no family with the given \a id exists.
5342 void MEDFileUMesh::setFamilyNameAttachedOnId(mcIdType id, const std::string& newFamName)
5344 std::string oldName=getFamilyNameGivenId(id);
5345 _families.erase(oldName);
5346 _families[newFamName]=id;
5350 * Removes a mesh of a given dimension.
5351 * \param [in] meshDimRelToMax - the relative dimension of interest.
5352 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
5354 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
5356 std::vector<int> levSet=getNonEmptyLevels();
5357 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
5358 if(it==levSet.end())
5359 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
5360 int pos=(-meshDimRelToMax);
5365 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
5366 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5367 * \param [in] m - the new mesh to set.
5368 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5370 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5371 * another node coordinates array.
5372 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5373 * to the existing meshes of other levels of \a this mesh.
5375 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5377 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5378 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5382 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5383 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5384 * \param [in] m - the new mesh to set.
5385 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5386 * writing \a this mesh in a MED file.
5387 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5389 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5390 * another node coordinates array.
5391 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5392 * to the existing meshes of other levels of \a this mesh.
5394 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5396 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5397 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5400 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5402 dealWithTinyInfo(m);
5403 std::vector<int> levSet=getNonEmptyLevels();
5404 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5406 if((DataArrayDouble *)_coords==0)
5408 DataArrayDouble *c=m->getCoords();
5413 if(m->getCoords()!=_coords)
5414 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5415 int sz=(-meshDimRelToMax)+1;
5416 if(sz>=(int)_ms.size())
5418 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5422 return _ms[-meshDimRelToMax];
5426 * This method allows to set at once the content of different levels in \a this.
5427 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5429 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5430 * \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.
5431 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5433 * \throw If \a there is a null pointer in \a ms.
5434 * \sa MEDFileUMesh::setMeshAtLevel
5436 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5440 const MEDCouplingUMesh *mRef=ms[0];
5442 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5443 std::string name(mRef->getName());
5444 const DataArrayDouble *coo(mRef->getCoords());
5447 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5449 const MEDCouplingUMesh *cur(*it);
5451 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5452 if(coo!=cur->getCoords())
5453 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5454 int mdim=cur->getMeshDimension();
5455 zeDim=std::max(zeDim,mdim);
5456 if(s.find(mdim)!=s.end())
5457 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5459 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5461 int mdim=(*it)->getMeshDimension();
5462 setName((*it)->getName());
5463 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5469 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5470 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5471 * The given meshes must share the same node coordinates array.
5472 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5473 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5474 * create in \a this mesh.
5475 * \throw If \a ms is empty.
5476 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5477 * to the existing meshes of other levels of \a this mesh.
5478 * \throw If the meshes in \a ms do not share the same node coordinates array.
5479 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5480 * of the given meshes.
5481 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5482 * \throw If names of some meshes in \a ms are equal.
5483 * \throw If \a ms includes a mesh with an empty name.
5485 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5488 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5489 int sz=(-meshDimRelToMax)+1;
5490 if(sz>=(int)_ms.size())
5492 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5493 DataArrayDouble *coo=checkMultiMesh(ms);
5494 if((DataArrayDouble *)_coords==0)
5500 if((DataArrayDouble *)_coords!=coo)
5501 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5502 std::vector<DataArrayIdType *> corr;
5503 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5504 std::vector< MCAuto<DataArrayIdType> > corr3(corr.begin(),corr.end());
5505 setMeshAtLevel(meshDimRelToMax,m,renum);
5506 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5507 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5511 * Creates groups at a given level in \a this mesh from a sequence of
5512 * meshes each representing a group.
5513 * The given meshes must share the same node coordinates array.
5514 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5515 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5516 * create in \a this mesh.
5517 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5519 * \throw If \a ms is empty.
5520 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5521 * to the existing meshes of other levels of \a this mesh.
5522 * \throw If the meshes in \a ms do not share the same node coordinates array.
5523 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5524 * of the given meshes.
5525 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5526 * \throw If names of some meshes in \a ms are equal.
5527 * \throw If \a ms includes a mesh with an empty name.
5529 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5532 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5533 int sz=(-meshDimRelToMax)+1;
5534 if(sz>=(int)_ms.size())
5536 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5537 DataArrayDouble *coo=checkMultiMesh(ms);
5538 if((DataArrayDouble *)_coords==0)
5544 if((DataArrayDouble *)_coords!=coo)
5545 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5546 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5547 std::vector< MCAuto<DataArrayIdType> > corr(ms.size());
5549 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5551 DataArrayIdType *arr=0;
5552 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5556 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5557 throw INTERP_KERNEL::Exception(oss.str().c_str());
5560 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5561 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5564 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5566 const DataArrayDouble *ret=ms[0]->getCoords();
5567 int mdim=ms[0]->getMeshDimension();
5568 for(unsigned int i=1;i<ms.size();i++)
5570 ms[i]->checkConsistencyLight();
5571 if(ms[i]->getCoords()!=ret)
5572 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5573 if(ms[i]->getMeshDimension()!=mdim)
5574 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5576 return const_cast<DataArrayDouble *>(ret);
5580 * Sets the family field of a given relative dimension.
5581 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5582 * the family field is set.
5583 * \param [in] famArr - the array of the family field.
5584 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5585 * \throw If \a famArr has an invalid size.
5587 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5589 if(meshDimRelToMaxExt==1)
5596 DataArrayDouble *coo(_coords);
5598 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5599 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5600 _fam_coords.takeRef(famArr);
5603 if(meshDimRelToMaxExt>1)
5604 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5605 int traducedRk=-meshDimRelToMaxExt;
5606 if(traducedRk>=(int)_ms.size())
5607 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5608 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5609 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5610 return _ms[traducedRk]->setFamilyArr(famArr);
5614 * Sets the optional numbers of mesh entities of a given dimension.
5615 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5616 * \param [in] renumArr - the array of the numbers.
5617 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5618 * \throw If \a renumArr has an invalid size.
5620 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5622 if(meshDimRelToMaxExt==1)
5626 _num_coords.nullify();
5627 _rev_num_coords.nullify();
5630 if(_coords.isNull())
5631 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5632 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5633 _num_coords.takeRef(renumArr);
5636 if(meshDimRelToMaxExt>1)
5637 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5638 int traducedRk=-meshDimRelToMaxExt;
5639 if(traducedRk>=(int)_ms.size())
5640 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5641 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5642 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5643 return _ms[traducedRk]->setRenumArr(renumArr);
5647 * Sets the optional names of mesh entities of a given dimension.
5648 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5649 * \param [in] nameArr - the array of the names.
5650 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5651 * \throw If \a nameArr has an invalid size.
5653 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5655 if(meshDimRelToMaxExt==1)
5662 DataArrayDouble *coo(_coords);
5664 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5665 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5666 _name_coords.takeRef(nameArr);
5669 if(meshDimRelToMaxExt>1)
5670 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5671 int traducedRk=-meshDimRelToMaxExt;
5672 if(traducedRk>=(int)_ms.size())
5673 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5674 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5675 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5676 return _ms[traducedRk]->setNameArr(nameArr);
5679 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
5681 if(meshDimRelToMaxExt!=1)
5682 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5684 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5685 _global_num_coords.takeRef(globalNumArr);
5688 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5690 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5691 if((const MEDFileUMeshSplitL1 *)(*it))
5692 (*it)->synchronizeTinyInfo(*this);
5696 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5698 void MEDFileUMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
5700 DataArrayIdType *arr=_fam_coords;
5702 arr->changeValue(oldId,newId);
5703 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5705 MEDFileUMeshSplitL1 *sp=(*it);
5708 sp->changeFamilyIdArr(oldId,newId);
5713 std::list< MCAuto<DataArrayIdType> > MEDFileUMesh::getAllNonNullFamilyIds() const
5715 std::list< MCAuto<DataArrayIdType> > ret;
5716 const DataArrayIdType *da(_fam_coords);
5718 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5719 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5721 const MEDFileUMeshSplitL1 *elt(*it);
5724 da=elt->getFamilyField();
5726 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5732 void MEDFileUMesh::computeRevNum() const
5734 if(_num_coords.isNotNull())
5737 mcIdType maxValue=_num_coords->getMaxValue(pos);
5738 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5742 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5744 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5747 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5749 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5750 ret.push_back((const DataArrayIdType *)_fam_nodes);
5751 ret.push_back((const DataArrayIdType *)_num_nodes);
5752 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5753 ret.push_back((const DataArrayIdType *)_fam_cells);
5754 ret.push_back((const DataArrayIdType *)_num_cells);
5755 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5756 ret.push_back((const DataArrayIdType *)_fam_faces);
5757 ret.push_back((const DataArrayIdType *)_num_faces);
5758 ret.push_back((const DataArrayIdType *)_rev_num_nodes);
5759 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5760 ret.push_back((const DataArrayIdType *)_rev_num_cells);
5761 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5765 mcIdType MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5767 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5768 if((const DataArrayIdType *)_fam_nodes)
5770 mcIdType val=_fam_nodes->getMaxValue(tmp);
5771 ret=std::max(ret,std::abs(val));
5773 if((const DataArrayIdType *)_fam_cells)
5775 mcIdType val=_fam_cells->getMaxValue(tmp);
5776 ret=std::max(ret,std::abs(val));
5778 if((const DataArrayIdType *)_fam_faces)
5780 mcIdType val=_fam_faces->getMaxValue(tmp);
5781 ret=std::max(ret,std::abs(val));
5786 mcIdType MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5788 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5789 if((const DataArrayIdType *)_fam_nodes)
5791 mcIdType val=_fam_nodes->getMaxValue(tmp);
5792 ret=std::max(ret,val);
5794 if((const DataArrayIdType *)_fam_cells)
5796 mcIdType val=_fam_cells->getMaxValue(tmp);
5797 ret=std::max(ret,val);
5799 if((const DataArrayIdType *)_fam_faces)
5801 mcIdType val=_fam_faces->getMaxValue(tmp);
5802 ret=std::max(ret,val);
5807 mcIdType MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5809 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
5810 if((const DataArrayIdType *)_fam_nodes)
5812 mcIdType val=_fam_nodes->getMinValue(tmp);
5813 ret=std::min(ret,val);
5815 if((const DataArrayIdType *)_fam_cells)
5817 mcIdType val=_fam_cells->getMinValue(tmp);
5818 ret=std::min(ret,val);
5820 if((const DataArrayIdType *)_fam_faces)
5822 mcIdType val=_fam_faces->getMinValue(tmp);
5823 ret=std::min(ret,val);
5828 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5830 if(!MEDFileMesh::isEqual(other,eps,what))
5832 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5835 what="Mesh types differ ! This is structured and other is NOT !";
5838 const DataArrayIdType *famc1=_fam_nodes;
5839 const DataArrayIdType *famc2=otherC->_fam_nodes;
5840 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5842 what="Mismatch of families arr on nodes ! One is defined and not other !";
5847 bool ret=famc1->isEqual(*famc2);
5850 what="Families arr on nodes differ !";
5855 famc2=otherC->_fam_cells;
5856 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5858 what="Mismatch of families arr on cells ! One is defined and not other !";
5863 bool ret=famc1->isEqual(*famc2);
5866 what="Families arr on cells differ !";
5871 famc2=otherC->_fam_faces;
5872 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5874 what="Mismatch of families arr on faces ! One is defined and not other !";
5879 bool ret=famc1->isEqual(*famc2);
5882 what="Families arr on faces differ !";
5887 famc2=otherC->_num_nodes;
5888 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5890 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5895 bool ret=famc1->isEqual(*famc2);
5898 what="Numbering arr on nodes differ !";
5903 famc2=otherC->_num_cells;
5904 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5906 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5911 bool ret=famc1->isEqual(*famc2);
5914 what="Numbering arr on cells differ !";
5919 famc2=otherC->_num_faces;
5920 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5922 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5927 bool ret=famc1->isEqual(*famc2);
5930 what="Numbering arr on faces differ !";
5934 const DataArrayAsciiChar *d1=_names_cells;
5935 const DataArrayAsciiChar *d2=otherC->_names_cells;
5936 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5938 what="Mismatch of naming arr on cells ! One is defined and not other !";
5943 bool ret=d1->isEqual(*d2);
5946 what="Naming arr on cells differ !";
5951 d2=otherC->_names_faces;
5952 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5954 what="Mismatch of naming arr on faces ! One is defined and not other !";
5959 bool ret=d1->isEqual(*d2);
5962 what="Naming arr on faces differ !";
5967 d2=otherC->_names_nodes;
5968 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5970 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5975 bool ret=d1->isEqual(*d2);
5978 what="Naming arr on nodes differ !";
5985 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5987 MEDFileMesh::clearNonDiscrAttributes();
5988 const DataArrayIdType *tmp=_fam_nodes;
5990 (const_cast<DataArrayIdType *>(tmp))->setName("");
5993 (const_cast<DataArrayIdType *>(tmp))->setName("");
5996 (const_cast<DataArrayIdType *>(tmp))->setName("");
5999 (const_cast<DataArrayIdType *>(tmp))->setName("");
6002 (const_cast<DataArrayIdType *>(tmp))->setName("");
6005 (const_cast<DataArrayIdType *>(tmp))->setName("");
6009 * Returns ids of mesh entities contained in given families of a given dimension.
6010 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
6012 * \param [in] fams - the names of the families of interest.
6013 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
6014 * returned instead of ids.
6015 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
6016 * numbers, if available and required, of mesh entities of the families. The caller
6017 * is to delete this array using decrRef() as it is no more needed.
6018 * \throw If the family field is missing for \a meshDimRelToMaxExt.
6020 DataArrayIdType *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
6022 std::vector<mcIdType> famIds(getFamiliesIds(fams));
6023 switch(meshDimRelToMaxExt)
6027 if((const DataArrayIdType *)_fam_nodes)
6029 MCAuto<DataArrayIdType> da;
6031 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
6033 da=_fam_nodes->findIdsEqualList(0,0);
6035 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
6040 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
6045 if((const DataArrayIdType *)_fam_cells)
6047 MCAuto<DataArrayIdType> da;
6049 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
6051 da=_fam_cells->findIdsEqualList(0,0);
6053 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
6058 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
6063 if((const DataArrayIdType *)_fam_faces)
6065 MCAuto<DataArrayIdType> da;
6067 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
6069 da=_fam_faces->findIdsEqualList(0,0);
6071 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
6076 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
6080 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
6082 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
6086 * Sets the family field of a given relative dimension.
6087 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
6088 * the family field is set.
6089 * \param [in] famArr - the array of the family field.
6090 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6091 * \throw If \a famArr has an invalid size.
6092 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
6094 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
6096 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
6098 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
6099 switch(meshDimRelToMaxExt)
6103 mcIdType nbCells(mesh->getNumberOfCells());
6105 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
6111 mcIdType nbNodes(mesh->getNumberOfNodes());
6113 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
6119 mcIdType nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
6121 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
6126 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
6133 * Sets the optional numbers of mesh entities of a given dimension.
6134 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6135 * \param [in] renumArr - the array of the numbers.
6136 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6137 * \throw If \a renumArr has an invalid size.
6138 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6140 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
6142 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
6144 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
6145 switch(meshDimRelToMaxExt)
6149 mcIdType nbCells=mesh->getNumberOfCells();
6150 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
6151 _num_cells=renumArr;
6156 mcIdType nbNodes=mesh->getNumberOfNodes();
6157 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
6158 _num_nodes=renumArr;
6163 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6164 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
6165 _num_faces=renumArr;
6169 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
6172 renumArr->incrRef();
6176 * Sets the optional names of mesh entities of a given dimension.
6177 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6178 * \param [in] nameArr - the array of the names.
6179 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6180 * \throw If \a nameArr has an invalid size.
6182 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
6184 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
6186 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
6187 switch(meshDimRelToMaxExt)
6191 mcIdType nbCells=mesh->getNumberOfCells();
6192 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
6193 _names_cells=nameArr;
6198 mcIdType nbNodes=mesh->getNumberOfNodes();
6199 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
6200 _names_nodes=nameArr;
6205 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6206 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
6207 _names_faces=nameArr;
6211 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6217 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
6219 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
6223 * Adds a group of nodes to \a this mesh.
6224 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6225 * The ids should be sorted and different each other (MED file norm).
6227 * \warning this method can alter default "FAMILLE_ZERO" family.
6228 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6230 * \throw If the node coordinates array is not set.
6231 * \throw If \a ids == \c NULL.
6232 * \throw If \a ids->getName() == "".
6233 * \throw If \a ids does not respect the MED file norm.
6234 * \throw If a group with name \a ids->getName() already exists.
6236 void MEDFileStructuredMesh::addNodeGroup(const DataArrayIdType *ids)
6242 * Adds a group of nodes/cells/faces/edges to \a this mesh.
6244 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6245 * The ids should be sorted and different each other (MED file norm).
6247 * \warning this method can alter default "FAMILLE_ZERO" family.
6248 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6250 * \throw If the node coordinates array is not set.
6251 * \throw If \a ids == \c NULL.
6252 * \throw If \a ids->getName() == "".
6253 * \throw If \a ids does not respect the MED file norm.
6254 * \throw If a group with name \a ids->getName() already exists.
6256 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
6258 DataArrayIdType *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
6259 addGroupUnderground(false,ids,fam);
6264 * Returns the family field for mesh entities of a given dimension.
6265 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6266 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6267 * each mesh entity belongs to. It can be \c NULL.
6268 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6270 const DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
6272 switch(meshDimRelToMaxExt)
6281 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6286 * Returns the family field for mesh entities of a given dimension.
6287 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6288 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6289 * each mesh entity belongs to. It can be \c NULL.
6290 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6292 DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
6294 switch(meshDimRelToMaxExt)
6303 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6308 * Returns the optional numbers of mesh entities of a given dimension.
6309 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6310 * \return const DataArrayIdType * - the array of the entity numbers.
6311 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6312 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6314 const DataArrayIdType *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
6316 switch(meshDimRelToMaxExt)
6325 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6330 * Returns the optional numbers of mesh entities of a given dimension transformed using
6331 * DataArrayIdType::invertArrayN2O2O2N().
6332 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6333 * \return const DataArrayIdType * - the array of the entity numbers transformed using
6334 * DataArrayIdType::invertArrayN2O2O2N().
6335 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6336 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6338 const DataArrayIdType *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
6340 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
6341 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
6342 if(meshDimRelToMaxExt==0)
6344 if((const DataArrayIdType *)_num_cells)
6347 mcIdType maxValue=_num_cells->getMaxValue(pos);
6348 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
6349 return _rev_num_cells;
6352 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
6356 if((const DataArrayIdType *)_num_nodes)
6359 mcIdType maxValue=_num_nodes->getMaxValue(pos);
6360 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
6361 return _rev_num_nodes;
6364 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6368 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6370 switch(meshDimRelToMaxExt)
6373 return _names_cells;
6375 return _names_nodes;
6377 return _names_faces;
6379 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6383 MCAuto<DataArrayIdType> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6385 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6389 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6390 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6392 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6394 std::vector<int> ret(1);
6399 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6400 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6402 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6404 std::vector<int> ret(2);
6410 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6412 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6414 std::vector<int> ret;
6415 const DataArrayIdType *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6426 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6428 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6430 std::vector<int> ret;
6431 const DataArrayIdType *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6442 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6444 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6446 std::vector<int> ret;
6447 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6458 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6460 bool MEDFileStructuredMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
6462 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6466 void MEDFileStructuredMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
6468 DataArrayIdType *arr=_fam_nodes;
6470 arr->changeValue(oldId,newId);
6473 arr->changeValue(oldId,newId);
6476 arr->changeValue(oldId,newId);
6479 std::list< MCAuto<DataArrayIdType> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6481 std::list< MCAuto<DataArrayIdType> > ret;
6482 const DataArrayIdType *da(_fam_nodes);
6484 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6487 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6490 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6494 void MEDFileStructuredMesh::deepCpyAttributes()
6496 if((const DataArrayIdType*)_fam_nodes)
6497 _fam_nodes=_fam_nodes->deepCopy();
6498 if((const DataArrayIdType*)_num_nodes)
6499 _num_nodes=_num_nodes->deepCopy();
6500 if((const DataArrayAsciiChar*)_names_nodes)
6501 _names_nodes=_names_nodes->deepCopy();
6502 if((const DataArrayIdType*)_fam_cells)
6503 _fam_cells=_fam_cells->deepCopy();
6504 if((const DataArrayIdType*)_num_cells)
6505 _num_cells=_num_cells->deepCopy();
6506 if((const DataArrayAsciiChar*)_names_cells)
6507 _names_cells=_names_cells->deepCopy();
6508 if((const DataArrayIdType*)_fam_faces)
6509 _fam_faces=_fam_faces->deepCopy();
6510 if((const DataArrayIdType*)_num_faces)
6511 _num_faces=_num_faces->deepCopy();
6512 if((const DataArrayAsciiChar*)_names_faces)
6513 _names_faces=_names_faces->deepCopy();
6514 if((const DataArrayIdType*)_rev_num_nodes)
6515 _rev_num_nodes=_rev_num_nodes->deepCopy();
6516 if((const DataArrayIdType*)_rev_num_cells)
6517 _rev_num_cells=_rev_num_cells->deepCopy();
6521 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6523 * \return a pointer to cartesian mesh that need to be managed by the caller.
6524 * \warning the returned pointer has to be managed by the caller.
6528 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6529 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6530 * \param [in] renum - it must be \c false.
6531 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6532 * delete using decrRef() as it is no more needed.
6534 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6538 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6539 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6540 switch(meshDimRelToMax)
6546 return const_cast<MEDCouplingStructuredMesh *>(m);
6551 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6552 buildMinusOneImplicitPartIfNeeded();
6553 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6559 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6564 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
6565 * To include nodes, call getFamsNonEmptyLevelsExt() method.
6566 * \param [in] fams - the name of the family of interest.
6567 * \return std::vector<int> - a sequence of the relative dimensions.
6569 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6571 std::vector<mcIdType> lvls;
6572 std::vector<mcIdType> famIds(getFamiliesIds(fams));
6573 const DataArrayIdType *famCells(_fam_cells),*famFaces(_fam_faces);
6574 if(famCells && famCells->presenceOfValue(famIds))
6576 if(famFaces && famFaces->presenceOfValue(famIds))
6582 * Returns all relative mesh levels (including nodes) where given families are defined.
6583 * \param [in] fams - the names of the families of interest.
6584 * \return std::vector<int> - a sequence of the relative dimensions.
6586 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6588 std::vector<mcIdType> lvls(getFamsNonEmptyLevels(fams));
6589 std::vector<mcIdType> famIds(getFamiliesIds(fams));
6590 const DataArrayIdType *famNodes(_fam_nodes);
6591 if(famNodes && famNodes->presenceOfValue(famIds))
6597 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6598 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6599 * \return mcIdType - the number of entities.
6600 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6602 mcIdType MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6604 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6606 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6607 switch(meshDimRelToMaxExt)
6610 return cmesh->getNumberOfCells();
6612 return cmesh->getNumberOfNodes();
6614 return cmesh->getNumberOfCellsOfSubLevelMesh();
6616 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6620 mcIdType MEDFileStructuredMesh::getNumberOfNodes() const
6622 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6624 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6625 return cmesh->getNumberOfNodes();
6628 mcIdType MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6630 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6632 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6633 switch(meshDimRelToMaxExt)
6636 return cmesh->getNumberOfCells();
6638 return cmesh->getNumberOfCellsOfSubLevelMesh();
6640 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6644 bool MEDFileStructuredMesh::hasImplicitPart() const
6650 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6652 mcIdType MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6654 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6655 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6658 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6659 if(cm.getReverseExtrudedType()!=gt)
6660 throw INTERP_KERNEL::Exception(MSG);
6661 buildImplicitPart();
6662 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6666 if(gt!=zeFaceMesh->getCellModelEnum())
6667 throw INTERP_KERNEL::Exception(MSG);
6668 return zeFaceMesh->getNumberOfCells();
6672 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6674 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6676 buildImplicitPart();
6679 void MEDFileStructuredMesh::buildImplicitPart() const
6681 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6683 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6684 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6687 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6689 _faces_if_necessary=0;
6693 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6694 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6696 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6698 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6701 return _faces_if_necessary;
6704 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6706 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6708 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6709 switch(meshDimRelToMax)
6713 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6718 int mdim(cmesh->getMeshDimension());
6720 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6721 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6725 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6729 mcIdType MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6731 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6734 return getNumberOfCellsAtLevel(0);
6737 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6739 if(st.getNumberOfItems()!=1)
6740 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 !");
6741 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6742 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6743 if(getNumberOfNodes()!=(mcIdType)nodesFetched.size())
6744 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6745 if(st[0].getPflName().empty())
6747 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6750 const DataArrayIdType *arr(globs->getProfile(st[0].getPflName()));
6751 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6752 mcIdType sz(ToIdType(nodesFetched.size()));
6753 for(const mcIdType *work=arr->begin();work!=arr->end();work++)
6755 std::vector<mcIdType> conn;
6756 cmesh->getNodeIdsOfCell(*work,conn);
6757 for(std::vector<mcIdType>::const_iterator it=conn.begin();it!=conn.end();it++)
6758 if(*it>=0 && *it<sz)
6759 nodesFetched[*it]=true;
6761 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6765 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6767 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6771 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6772 MCAuto<DataArrayIdType>& famCells, MCAuto<DataArrayIdType>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6774 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6775 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6776 mcIdType nbOfElt(0);
6777 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6780 if(!mrs || mrs->isCellFamilyFieldReading())
6782 MCAuto<DataArrayMedInt> miFamCells=DataArrayMedInt::New();
6783 miFamCells->alloc(nbOfElt,1);
6784 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miFamCells->getPointer()));
6785 famCells = FromMedIntArray<mcIdType>( miFamCells );
6788 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6791 if(!mrs || mrs->isCellNumFieldReading())
6793 MCAuto<DataArrayMedInt> miNumCells=DataArrayMedInt::New();
6794 miNumCells->alloc(nbOfElt,1);
6795 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miNumCells->getPointer()));
6796 numCells = FromMedIntArray<mcIdType>( miNumCells );
6799 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6802 if(!mrs || mrs->isCellNameFieldReading())
6804 namesCells=DataArrayAsciiChar::New();
6805 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6806 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6807 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6812 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6814 setName(strm->getName());
6815 setDescription(strm->getDescription());
6816 setUnivName(strm->getUnivName());
6817 setIteration(strm->getIteration());
6818 setOrder(strm->getOrder());
6819 setTimeValue(strm->getTime());
6820 setTimeUnit(strm->getTimeUnit());
6821 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6822 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6823 mcIdType nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6826 if(!mrs || mrs->isNodeFamilyFieldReading())
6828 mcIdType nbNodes(getNumberOfNodes());
6830 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6831 MCAuto<DataArrayMedInt> miFamNodes=DataArrayMedInt::New();
6832 miFamNodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6833 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...
6834 miFamNodes->fillWithZero();
6835 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miFamNodes->getPointer()));
6836 _fam_nodes = FromMedIntArray<mcIdType>( miFamNodes );
6839 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6842 if(!mrs || mrs->isNodeNumFieldReading())
6844 MCAuto<DataArrayMedInt> miNumNodes=DataArrayMedInt::New();
6845 miNumNodes->alloc(nbOfElt,1);
6846 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miNumNodes->getPointer()));
6847 _num_nodes = FromMedIntArray<mcIdType>( miNumNodes );
6850 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6853 if(!mrs || mrs->isNodeNameFieldReading())
6855 _names_nodes=DataArrayAsciiChar::New();
6856 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6857 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6858 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6861 int meshDim(getStructuredMesh()->getMeshDimension());
6862 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6864 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6867 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6869 int meshDim(getStructuredMesh()->getMeshDimension());
6870 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6872 if((const DataArrayIdType *)_fam_cells)
6873 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_fam_cells->getNumberOfTuples()),ToMedIntArray(_fam_cells)->getConstPointer()));
6874 if((const DataArrayIdType *)_fam_faces)
6875 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_fam_faces->getNumberOfTuples()),ToMedIntArray(_fam_faces)->getConstPointer()));
6876 if((const DataArrayIdType *)_fam_nodes)
6877 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_fam_nodes->getNumberOfTuples()),ToMedIntArray(_fam_nodes)->getConstPointer()));
6878 if((const DataArrayIdType *)_num_cells)
6879 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_num_cells->getNumberOfTuples()),ToMedIntArray(_num_cells)->getConstPointer()));
6880 if((const DataArrayIdType *)_num_faces)
6881 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_num_faces->getNumberOfTuples()),ToMedIntArray(_num_faces)->getConstPointer()));
6882 if((const DataArrayIdType *)_num_nodes)
6883 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_num_nodes->getNumberOfTuples()),ToMedIntArray(_num_nodes)->getConstPointer()));
6884 if((const DataArrayAsciiChar *)_names_cells)
6886 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6888 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6889 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6890 throw INTERP_KERNEL::Exception(oss.str().c_str());
6892 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_names_cells->getNumberOfTuples()),_names_cells->getConstPointer()));
6894 if((const DataArrayAsciiChar *)_names_faces)
6896 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6898 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6899 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6900 throw INTERP_KERNEL::Exception(oss.str().c_str());
6902 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_names_faces->getNumberOfTuples()),_names_faces->getConstPointer()));
6904 if((const DataArrayAsciiChar *)_names_nodes)
6906 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6908 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6909 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6910 throw INTERP_KERNEL::Exception(oss.str().c_str());
6912 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_names_nodes->getNumberOfTuples()),_names_nodes->getConstPointer()));
6915 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6919 * Returns an empty instance of MEDFileCMesh.
6920 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6921 * mesh using decrRef() as it is no more needed.
6923 MEDFileCMesh *MEDFileCMesh::New()
6925 return new MEDFileCMesh;
6929 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6930 * file. The first mesh in the file is loaded.
6931 * \param [in] fileName - the name of MED file to read.
6932 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6933 * mesh using decrRef() as it is no more needed.
6934 * \throw If the file is not readable.
6935 * \throw If there is no meshes in the file.
6936 * \throw If the mesh in the file is not a Cartesian one.
6938 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6940 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6941 return New(fid,mrs);
6944 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6946 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6950 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6951 * file. The mesh to load is specified by its name and numbers of a time step and an
6953 * \param [in] fileName - the name of MED file to read.
6954 * \param [in] mName - the name of the mesh to read.
6955 * \param [in] dt - the number of a time step.
6956 * \param [in] it - the number of an iteration.
6957 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6958 * mesh using decrRef() as it is no more needed.
6959 * \throw If the file is not readable.
6960 * \throw If there is no mesh with given attributes in the file.
6961 * \throw If the mesh in the file is not a Cartesian one.
6963 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6965 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6966 return New(fid,mName,dt,it,mrs);
6969 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6971 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6974 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6976 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6979 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6981 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6982 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6987 * Returns the dimension on cells in \a this mesh.
6988 * \return int - the mesh dimension.
6989 * \throw If there are no cells in this mesh.
6991 int MEDFileCMesh::getMeshDimension() const
6993 if(!((const MEDCouplingCMesh*)_cmesh))
6994 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6995 return _cmesh->getMeshDimension();
6999 * Returns the dimension on nodes in \a this mesh.
7000 * \return int - the space dimension.
7001 * \throw If there are no cells in this mesh.
7003 int MEDFileCMesh::getSpaceDimension() const
7005 if(!((const MEDCouplingCMesh*)_cmesh))
7006 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
7007 return _cmesh->getSpaceDimension();
7011 * Returns a string describing \a this mesh.
7012 * \return std::string - the mesh information string.
7014 std::string MEDFileCMesh::simpleRepr() const
7016 return MEDFileStructuredMesh::simpleRepr();
7020 * Returns a full textual description of \a this mesh.
7021 * \return std::string - the string holding the mesh description.
7023 std::string MEDFileCMesh::advancedRepr() const
7025 return simpleRepr();
7028 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
7030 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
7034 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
7036 return new MEDFileCMesh;
7039 MEDFileCMesh *MEDFileCMesh::deepCopy() const
7041 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
7042 ret->deepCpyEquivalences(*this);
7043 if((const MEDCouplingCMesh*)_cmesh)
7044 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
7045 ret->deepCpyAttributes();
7050 * Checks if \a this and another mesh are equal.
7051 * \param [in] other - the mesh to compare with.
7052 * \param [in] eps - a precision used to compare real values.
7053 * \param [in,out] what - the string returning description of unequal data.
7054 * \return bool - \c true if the meshes are equal, \c false, else.
7056 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7058 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7060 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
7063 what="Mesh types differ ! This is cartesian and other is NOT !";
7066 clearNonDiscrAttributes();
7067 otherC->clearNonDiscrAttributes();
7068 const MEDCouplingCMesh *coo1=_cmesh;
7069 const MEDCouplingCMesh *coo2=otherC->_cmesh;
7070 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7072 what="Mismatch of cartesian meshes ! One is defined and not other !";
7077 bool ret=coo1->isEqual(coo2,eps);
7080 what="cartesian meshes differ !";
7088 * Clears redundant attributes of incorporated data arrays.
7090 void MEDFileCMesh::clearNonDiscrAttributes() const
7092 MEDFileStructuredMesh::clearNonDiscrAttributes();
7093 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
7096 MEDFileCMesh::MEDFileCMesh()
7100 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7103 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7105 catch(INTERP_KERNEL::Exception& e)
7110 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7112 MEDCoupling::MEDCouplingMeshType meshType;
7115 MEDCoupling::MEDCouplingAxisType axType;
7116 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7117 if(meshType!=CARTESIAN)
7119 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
7120 throw INTERP_KERNEL::Exception(oss.str().c_str());
7122 MEDFileCMeshL2 loaderl2;
7123 loaderl2.loadAll(fid,mid,mName,dt,it);
7124 setAxisType(axType);
7125 MEDCouplingCMesh *mesh=loaderl2.getMesh();
7128 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7132 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
7133 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
7135 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
7137 synchronizeTinyInfoOnLeaves();
7141 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
7143 synchronizeTinyInfoOnLeaves();
7148 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
7149 * \param [in] m - the new MEDCouplingCMesh to refer to.
7150 * \throw If the name or the description of \a this mesh and \a m are not empty and are
7153 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
7155 dealWithTinyInfo(m);
7161 MEDFileMesh *MEDFileCMesh::cartesianize() const
7163 if(getAxisType()==AX_CART)
7166 return const_cast<MEDFileCMesh *>(this);
7170 const MEDCouplingCMesh *cmesh(getMesh());
7172 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7173 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
7174 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
7175 clmesh->setCoords(coords);
7176 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
7177 ret->MEDFileStructuredMesh::operator=(*this);
7178 ret->setMesh(clmesh);
7179 ret->setAxisType(AX_CART);
7184 void MEDFileCMesh::writeMeshLL(med_idt fid) const
7186 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7187 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7188 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7189 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7190 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7191 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7192 int spaceDim(_cmesh->getSpaceDimension());
7193 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7194 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7195 for(int i=0;i<spaceDim;i++)
7197 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
7199 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7200 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
7201 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
7203 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7205 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7206 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
7207 for(int i=0;i<spaceDim;i++)
7209 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
7210 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,ToMedInt(da->getNumberOfTuples()),da->getConstPointer()));
7213 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7214 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7217 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
7219 const MEDCouplingCMesh *cmesh=_cmesh;
7222 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
7223 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
7224 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
7225 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
7228 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
7230 return new MEDFileCurveLinearMesh;
7233 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
7235 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
7238 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
7240 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7241 return New(fid,mrs);
7244 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7246 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7247 return New(fid,mName,dt,it,mrs);
7250 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7252 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
7255 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
7257 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
7260 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
7262 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
7263 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
7267 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
7269 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7273 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
7275 return new MEDFileCurveLinearMesh;
7278 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
7280 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7281 ret->deepCpyEquivalences(*this);
7282 if((const MEDCouplingCurveLinearMesh*)_clmesh)
7283 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
7284 ret->deepCpyAttributes();
7288 int MEDFileCurveLinearMesh::getMeshDimension() const
7290 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7291 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get mesh dimension because no mesh set !");
7292 return _clmesh->getMeshDimension();
7295 int MEDFileCurveLinearMesh::getSpaceDimension() const
7297 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7298 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get space dimension because no mesh set !");
7299 return _clmesh->getSpaceDimension();
7302 std::string MEDFileCurveLinearMesh::simpleRepr() const
7304 return MEDFileStructuredMesh::simpleRepr();
7307 std::string MEDFileCurveLinearMesh::advancedRepr() const
7309 return simpleRepr();
7312 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7314 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7316 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
7319 what="Mesh types differ ! This is curve linear and other is NOT !";
7322 clearNonDiscrAttributes();
7323 otherC->clearNonDiscrAttributes();
7324 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
7325 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
7326 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7328 what="Mismatch of curve linear meshes ! One is defined and not other !";
7333 bool ret=coo1->isEqual(coo2,eps);
7336 what="curve linear meshes differ !";
7343 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
7345 MEDFileStructuredMesh::clearNonDiscrAttributes();
7346 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
7349 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
7351 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
7354 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
7355 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
7356 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
7357 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
7360 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
7362 synchronizeTinyInfoOnLeaves();
7366 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
7368 dealWithTinyInfo(m);
7374 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
7376 if(getAxisType()==AX_CART)
7379 return const_cast<MEDFileCurveLinearMesh *>(this);
7383 const MEDCouplingCurveLinearMesh *mesh(getMesh());
7385 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7386 const DataArrayDouble *coords(mesh->getCoords());
7388 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
7389 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7390 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
7391 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7392 mesh2->setCoords(coordsCart);
7393 ret->setMesh(mesh2);
7394 ret->setAxisType(AX_CART);
7399 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7401 synchronizeTinyInfoOnLeaves();
7405 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7409 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7412 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7414 catch(INTERP_KERNEL::Exception& e)
7419 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7421 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7422 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7423 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7424 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7425 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7426 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7427 int spaceDim=_clmesh->getSpaceDimension();
7428 int meshDim=_clmesh->getMeshDimension();
7429 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7430 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7431 const DataArrayDouble *coords=_clmesh->getCoords();
7433 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7434 for(int i=0;i<spaceDim;i++)
7436 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7438 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7439 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
7440 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
7442 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7444 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7445 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7446 std::vector<mcIdType> nodeGridSt=_clmesh->getNodeGridStructure();
7447 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,ToMedIntArray(nodeGridSt)->getConstPointer()));
7449 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,ToMedInt(coords->getNumberOfTuples()),coords->begin()));
7451 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7452 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7455 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7457 MEDCoupling::MEDCouplingMeshType meshType;
7460 MEDCoupling::MEDCouplingAxisType axType;
7461 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7462 setAxisType(axType);
7463 if(meshType!=CURVE_LINEAR)
7465 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7466 throw INTERP_KERNEL::Exception(oss.str().c_str());
7468 MEDFileCLMeshL2 loaderl2;
7469 loaderl2.loadAll(fid,mid,mName,dt,it);
7470 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7473 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7476 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7478 return new MEDFileMeshMultiTS;
7481 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7483 return new MEDFileMeshMultiTS(fid);
7486 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7488 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7492 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7494 return new MEDFileMeshMultiTS(fid,mName);
7497 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7499 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7500 return New(fid,mName);
7503 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7505 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7506 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7508 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7509 if((const MEDFileMesh *)*it)
7510 meshOneTs[i]=(*it)->deepCopy();
7511 ret->_mesh_one_ts=meshOneTs;
7515 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7517 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7520 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7522 std::vector<const BigMemoryObject *> ret;
7523 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7524 ret.push_back((const MEDFileMesh *)*it);
7528 std::string MEDFileMeshMultiTS::getName() const
7530 if(_mesh_one_ts.empty())
7531 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7532 return _mesh_one_ts[0]->getName();
7535 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7537 std::string oldName(getName());
7538 std::vector< std::pair<std::string,std::string> > v(1);
7539 v[0].first=oldName; v[0].second=newMeshName;
7543 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7546 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7548 MEDFileMesh *cur(*it);
7550 ret=cur->changeNames(modifTab) || ret;
7555 void MEDFileMeshMultiTS::cartesianizeMe()
7557 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7559 MEDFileMesh *cur(*it);
7562 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7568 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7570 if(_mesh_one_ts.empty())
7571 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7572 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7575 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7578 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7579 _mesh_one_ts.resize(1);
7580 mesh1TimeStep->incrRef();
7581 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7582 _mesh_one_ts[0]=mesh1TimeStep;
7585 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7587 if ( MEDFileMesh* m = getOneTimeStep() )
7588 return m->getJoints();
7593 * \brief Set Joints that are common to all time-stamps
7595 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7597 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7599 (*it)->setJoints( joints );
7603 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7605 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7606 if((*it).isNotNull())
7607 if((*it)->presenceOfStructureElements())
7612 void MEDFileMeshMultiTS::killStructureElements()
7614 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7615 if((*it).isNotNull())
7616 (*it)->killStructureElements();
7619 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7621 MEDFileJoints *joints(getJoints());
7622 bool jointsWritten(false);
7624 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7626 if ( jointsWritten )
7627 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7629 jointsWritten = true;
7631 (*it)->copyOptionsFrom(*this);
7632 (*it)->writeLL(fid);
7635 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7638 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7640 MEDFileJoints *joints(0);
7641 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7643 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7644 joints = getOneTimeStep()->getJoints();
7646 _mesh_one_ts.clear(); //for the moment to be improved
7647 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7650 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7654 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7657 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7660 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7661 throw INTERP_KERNEL::Exception(oss.str().c_str());
7664 MEDCoupling::MEDCouplingMeshType meshType;
7666 MEDCoupling::MEDCouplingAxisType dummy3;
7667 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7668 loadFromFile(fid,ms.front());
7670 catch(INTERP_KERNEL::Exception& e)
7675 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7678 loadFromFile(fid,mName);
7680 catch(INTERP_KERNEL::Exception& e)
7685 MEDFileMeshes *MEDFileMeshes::New()
7687 return new MEDFileMeshes;
7690 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7692 return new MEDFileMeshes(fid);
7695 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7697 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7701 void MEDFileMeshes::writeLL(med_idt fid) const
7703 checkConsistencyLight();
7704 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7706 (*it)->copyOptionsFrom(*this);
7707 (*it)->writeLL(fid);
7711 // MEDFileMeshes::writ checkConsistencyLight();
7713 int MEDFileMeshes::getNumberOfMeshes() const
7715 return (int)_meshes.size();
7718 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7720 return new MEDFileMeshesIterator(this);
7723 /** Return a borrowed reference (caller is not responsible) */
7724 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7726 if(i<0 || i>=(int)_meshes.size())
7728 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7729 throw INTERP_KERNEL::Exception(oss.str().c_str());
7731 return _meshes[i]->getOneTimeStep();
7734 /** Return a borrowed reference (caller is not responsible) */
7735 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7737 std::vector<std::string> ms=getMeshesNames();
7738 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7741 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7742 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7743 throw INTERP_KERNEL::Exception(oss.str().c_str());
7745 return getMeshAtPos((int)std::distance(ms.begin(),it));
7748 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7750 std::vector<std::string> ret(_meshes.size());
7752 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7754 const MEDFileMeshMultiTS *f=(*it);
7757 ret[i]=f->getName();
7761 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7762 throw INTERP_KERNEL::Exception(oss.str().c_str());
7768 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7771 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7773 MEDFileMeshMultiTS *cur(*it);
7775 ret=cur->changeNames(modifTab) || ret;
7780 void MEDFileMeshes::cartesianizeMe()
7782 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7784 MEDFileMeshMultiTS *cur(*it);
7786 cur->cartesianizeMe();
7790 void MEDFileMeshes::resize(int newSize)
7792 _meshes.resize(newSize);
7795 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7798 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7799 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7800 elt->setOneTimeStep(mesh);
7801 _meshes.push_back(elt);
7804 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7807 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7808 if(i>=(int)_meshes.size())
7809 _meshes.resize(i+1);
7810 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7811 elt->setOneTimeStep(mesh);
7815 void MEDFileMeshes::destroyMeshAtPos(int i)
7817 if(i<0 || i>=(int)_meshes.size())
7819 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7820 throw INTERP_KERNEL::Exception(oss.str().c_str());
7822 _meshes.erase(_meshes.begin()+i);
7825 void MEDFileMeshes::loadFromFile(med_idt fid)
7827 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7829 _meshes.resize(ms.size());
7830 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7831 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7834 MEDFileMeshes::MEDFileMeshes()
7838 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7843 catch(INTERP_KERNEL::Exception& /*e*/)
7847 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7849 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7851 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7852 if((const MEDFileMeshMultiTS *)*it)
7853 meshes[i]=(*it)->deepCopy();
7854 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7855 ret->_meshes=meshes;
7859 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7861 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7864 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7866 std::vector<const BigMemoryObject *> ret;
7867 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7868 ret.push_back((const MEDFileMeshMultiTS *)*it);
7872 std::string MEDFileMeshes::simpleRepr() const
7874 std::ostringstream oss;
7875 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7876 simpleReprWithoutHeader(oss);
7880 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7882 int nbOfMeshes=getNumberOfMeshes();
7883 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7884 std::vector<std::string> mns=getMeshesNames();
7885 for(int i=0;i<nbOfMeshes;i++)
7886 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7889 void MEDFileMeshes::checkConsistencyLight() const
7891 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7893 std::set<std::string> s;
7894 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7896 const MEDFileMeshMultiTS *elt=(*it);
7899 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7900 throw INTERP_KERNEL::Exception(oss.str().c_str());
7902 std::size_t sz=s.size();
7903 s.insert(std::string((*it)->getName()));
7906 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7907 throw INTERP_KERNEL::Exception(oss.str().c_str());
7912 bool MEDFileMeshes::presenceOfStructureElements() const
7914 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7915 if((*it).isNotNull())
7916 if((*it)->presenceOfStructureElements())
7921 void MEDFileMeshes::killStructureElements()
7923 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7924 if((*it).isNotNull())
7925 (*it)->killStructureElements();
7928 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7933 _nb_iter=ms->getNumberOfMeshes();
7937 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7941 MEDFileMesh *MEDFileMeshesIterator::nextt()
7943 if(_iter_id<_nb_iter)
7945 MEDFileMeshes *ms(_ms);
7947 return ms->getMeshAtPos(_iter_id++);
7955 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7957 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7958 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7960 if(geoType==MED_NO_GEOTYPE)
7961 return INTERP_KERNEL::NORM_ERROR;
7962 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7963 throw INTERP_KERNEL::Exception(oss.str());
7965 return typmai2[std::distance(typmai,pos)];
7968 med_geometry_type MEDFileMesh::ConvertToMEDFileGeoType(INTERP_KERNEL::NormalizedCellType geoType)
7970 INTERP_KERNEL::NormalizedCellType *pos(std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,geoType));
7971 if(pos==typmai2+MED_N_CELL_FIXED_GEO)
7973 THROW_IK_EXCEPTION("MEDFileMesh::ConvertToMEDFileGeoType : no entry for " << geoType);
7975 return typmai[std::distance(typmai2,pos)];
7978 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7986 case MED_NODE_ELEMENT:
7990 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7991 throw INTERP_KERNEL::Exception(oss.str());