1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileFieldOverView.hxx"
23 #include "MEDFileField.hxx"
24 #include "MEDLoader.hxx"
25 #include "MEDLoaderNS.hxx"
26 #include "MEDFileSafeCaller.txx"
27 #include "MEDLoaderBase.hxx"
29 #include "MEDCouplingUMesh.hxx"
30 #include "MEDCouplingMappedExtrudedMesh.hxx"
31 #include "MEDCouplingMemArray.txx"
33 #include "InterpKernelAutoPtr.hxx"
38 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
39 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
40 extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE];
42 using namespace MEDCoupling;
44 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
46 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
48 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
52 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
54 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
55 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
57 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
58 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
59 ret+=(*it2).capacity();
61 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
62 ret+=(*it).first.capacity()+sizeof(mcIdType);
66 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
68 std::vector<const BigMemoryObject *> ret(1);
69 ret[0]=(const MEDFileEquivalences *)_equiv;
74 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
75 * file. The first mesh in the file is loaded.
76 * \param [in] fileName - the name of MED file to read.
77 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
78 * mesh using decrRef() as it is no more needed.
79 * \throw If the file is not readable.
80 * \throw If there is no meshes in the file.
81 * \throw If the mesh in the file is of a not supported type.
83 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
85 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
89 MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
91 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
94 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
95 throw INTERP_KERNEL::Exception(oss.str().c_str());
97 MEDCoupling::MEDCouplingMeshType meshType;
100 MEDCoupling::MEDCouplingAxisType dummy3;
101 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
102 MCAuto<MEDFileMesh> ret;
107 ret=MEDFileUMesh::New();
112 ret=MEDFileCMesh::New();
117 ret=MEDFileCurveLinearMesh::New();
122 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
123 throw INTERP_KERNEL::Exception(oss.str().c_str());
126 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
131 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
132 * file. The mesh to load is specified by its name and numbers of a time step and an
134 * \param [in] fileName - the name of MED file to read.
135 * \param [in] mName - the name of the mesh to read.
136 * \param [in] dt - the number of a time step.
137 * \param [in] it - the number of an iteration.
138 * \param [in] joints - the sub-domain joints to use instead of those that can be read
139 * from the MED file. Usually this joints are those just read by another iteration
140 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
141 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
142 * mesh using decrRef() as it is no more needed.
143 * \throw If the file is not readable.
144 * \throw If there is no mesh with given attributes in the file.
145 * \throw If the mesh in the file is of a not supported type.
147 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
149 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
150 return New(fid,mName,dt,it,mrs,joints);
153 MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
155 MEDCoupling::MEDCouplingMeshType meshType;
158 MEDCoupling::MEDCouplingAxisType dummy3;
159 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
160 MCAuto<MEDFileMesh> ret;
165 ret=MEDFileUMesh::New();
170 ret=MEDFileCMesh::New();
175 ret=MEDFileCurveLinearMesh::New();
180 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
181 throw INTERP_KERNEL::Exception(oss.str().c_str());
184 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
189 * Writes \a this mesh into an open MED file specified by its descriptor.
190 * \param [in] fid - the MED file descriptor.
191 * \throw If the mesh name is not set.
192 * \throw If the file is open for reading only.
193 * \throw If the writing mode == 1 and the same data is present in an existing file.
195 void MEDFileMesh::writeLL(med_idt fid) const
198 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
200 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
203 const MEDFileEquivalences *eqs(_equiv);
209 * Checks if \a this and another mesh are equal.
210 * \param [in] other - the mesh to compare with.
211 * \param [in] eps - a precision used to compare real values.
212 * \param [in,out] what - the string returning description of unequal data.
213 * \return bool - \c true if the meshes are equal, \c false, else.
215 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
217 if(_order!=other->_order)
219 what="Orders differ !";
222 if(_iteration!=other->_iteration)
224 what="Iterations differ !";
227 if(fabs(_time-other->_time)>eps)
229 what="Time values differ !";
232 if(_dt_unit!=other->_dt_unit)
234 what="Time units differ !";
237 if(_name!=other->_name)
239 what="Names differ !";
242 //univ_name has been ignored -> not a bug because it is a mutable attribute
243 if(_desc_name!=other->_desc_name)
245 what="Description names differ !";
248 if(!areGrpsEqual(other,what))
250 if(!areFamsEqual(other,what))
252 if(!areEquivalencesEqual(other,what))
257 void MEDFileMesh::setName(const std::string& name)
263 * Clears redundant attributes of incorporated data arrays.
265 void MEDFileMesh::clearNonDiscrAttributes() const
270 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
272 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
274 if((*it).first==_name)
284 * Copies data on groups and families from another mesh.
285 * \param [in] other - the mesh to copy the data from.
287 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
289 _groups=other._groups;
290 _families=other._families;
295 * This method clear all the groups in the map.
296 * So this method does not operate at all on arrays.
297 * So this method can lead to orphan families.
299 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
301 void MEDFileMesh::clearGrpMap()
307 * This method clear all the families in the map.
308 * So this method does not operate at all on arrays.
309 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
311 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
313 void MEDFileMesh::clearFamMap()
319 * This method clear all the families and groups in the map.
320 * So this method does not operate at all on arrays.
321 * As all groups and families entry will be removed after
322 * 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.
324 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
326 void MEDFileMesh::clearFamGrpMaps()
333 * Returns names of families constituting a group.
334 * \param [in] name - the name of the group of interest.
335 * \return std::vector<std::string> - a sequence of names of the families.
336 * \throw If the name of a nonexistent group is specified.
338 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
340 std::string oname(name);
341 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
342 if(it==_groups.end())
344 std::vector<std::string> grps=getGroupsNames();
345 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
346 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
347 throw INTERP_KERNEL::Exception(oss.str().c_str());
353 * Returns names of families constituting some groups.
354 * \param [in] grps - a sequence of names of groups of interest.
355 * \return std::vector<std::string> - a sequence of names of the families.
356 * \throw If a name of a nonexistent group is present in \a grps.
358 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
360 std::set<std::string> fams;
361 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
363 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
364 if(it2==_groups.end())
366 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
367 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
368 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
369 throw INTERP_KERNEL::Exception(oss.str().c_str());
371 fams.insert((*it2).second.begin(),(*it2).second.end());
373 std::vector<std::string> fams2(fams.begin(),fams.end());
378 * Returns ids of families constituting a group.
379 * \param [in] name - the name of the group of interest.
380 * \return std::vector<int> - sequence of ids of the families.
381 * \throw If the name of a nonexistent group is specified.
383 std::vector<mcIdType> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
385 std::string oname(name);
386 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
387 std::vector<std::string> grps=getGroupsNames();
388 if(it==_groups.end())
390 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
391 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
392 throw INTERP_KERNEL::Exception(oss.str().c_str());
394 return getFamiliesIds((*it).second);
398 * Sets names of families constituting a group. If data on families of this group is
399 * already present, it is overwritten. Every family in \a fams is checked, and if a
400 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
401 * \param [in] name - the name of the group of interest.
402 * \param [in] fams - a sequence of names of families constituting the group.
404 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
406 std::string oname(name);
408 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
410 std::map<std::string,mcIdType>::iterator it2=_families.find(*it1);
411 if(it2==_families.end())
417 * Sets families constituting a group. The families are specified by their ids.
418 * If a family name is not found by its id, an exception is thrown.
419 * If several families have same id, the first one in lexical order is taken.
420 * \param [in] name - the name of the group of interest.
421 * \param [in] famIds - a sequence of ids of families constituting the group.
422 * \throw If a family name is not found by its id.
424 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<mcIdType>& famIds)
426 std::string oname(name);
427 std::vector<std::string> fams(famIds.size());
429 for(std::vector<mcIdType>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
431 std::string name2=getFamilyNameGivenId(*it1);
438 * Returns names of groups including a given family.
439 * \param [in] name - the name of the family of interest.
440 * \return std::vector<std::string> - a sequence of names of groups including the family.
442 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
444 std::vector<std::string> ret;
445 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
447 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
450 ret.push_back((*it1).first);
458 * Adds an existing family to groups.
459 * \param [in] famName - a name of family to add to \a grps.
460 * \param [in] grps - a sequence of group names to add the family in.
461 * \throw If a family named \a famName not yet exists.
463 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
465 std::string fName(famName);
466 const std::map<std::string,mcIdType>::const_iterator it=_families.find(fName);
467 if(it==_families.end())
469 std::vector<std::string> fams=getFamiliesNames();
470 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
471 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
472 throw INTERP_KERNEL::Exception(oss.str().c_str());
474 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
476 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
477 if(it2!=_groups.end())
478 (*it2).second.push_back(fName);
481 std::vector<std::string> grps2(1,fName);
488 * Returns names of all groups of \a this mesh.
489 * \return std::vector<std::string> - a sequence of group names.
491 std::vector<std::string> MEDFileMesh::getGroupsNames() const
493 std::vector<std::string> ret(_groups.size());
495 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
501 * Returns names of all families of \a this mesh.
502 * \return std::vector<std::string> - a sequence of family names.
504 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
506 std::vector<std::string> ret(_families.size());
508 for(std::map<std::string, mcIdType >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
514 * Returns names of all families of \a this mesh but like they would be in file.
515 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
516 * 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 !
517 * For your information internally in memory such families are renamed to have a nicer API.
519 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
521 std::vector<std::string> ret(getFamiliesNames());
522 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
527 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
528 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
529 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
532 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
534 std::vector<std::string> ret;
535 std::vector<std::string> allGrps(getGroupsNames());
536 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
538 std::vector<mcIdType> levs(getGrpNonEmptyLevelsExt((*it)));
539 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
546 * Returns all relative mesh levels (including nodes) where a given group is defined.
547 * \param [in] grp - the name of the group of interest.
548 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
550 std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
552 std::vector<std::string> fams(getFamiliesOnGroup(grp));
553 return getFamsNonEmptyLevelsExt(fams);
557 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
558 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
559 * \param [in] grps - a sequence of names of the groups of interest.
560 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
562 std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
564 std::vector<std::string> fams(getFamiliesOnGroups(grps));
565 return getFamsNonEmptyLevels(fams);
569 * Returns all relative mesh levels (including nodes) where given groups are defined.
570 * \param [in] grps - a sequence of names of the groups of interest.
571 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
573 std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
575 std::vector<std::string> fams(getFamiliesOnGroups(grps));
576 return getFamsNonEmptyLevelsExt(fams);
580 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
581 * To include nodes, call getGrpNonEmptyLevelsExt() method.
582 * \param [in] grp - the name of the group of interest.
583 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
585 std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
587 std::vector<std::string> fams(getFamiliesOnGroup(grp));
588 return getFamsNonEmptyLevels(fams);
592 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
593 * To include nodes, call getFamNonEmptyLevelsExt() method.
594 * \param [in] fam - the name of the family of interest.
595 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
597 std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
599 std::vector<std::string> fams(1,std::string(fam));
600 return getFamsNonEmptyLevels(fams);
604 * Returns all relative mesh levels (including nodes) where a given family is defined.
605 * \param [in] fam - the name of the family of interest.
606 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
608 std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
610 std::vector<std::string> fams(1,std::string(fam));
611 return getFamsNonEmptyLevelsExt(fams);
614 std::string MEDFileMesh::GetMagicFamilyStr()
616 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
620 * Changes a name of every family, included in one group only, to be same as the group name.
621 * \throw If there are families with equal names in \a this mesh.
623 void MEDFileMesh::assignFamilyNameWithGroupName()
625 std::map<std::string, std::vector<std::string> > groups(_groups);
626 std::map<std::string,mcIdType> newFams;
627 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
629 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
630 if(grps.size()==1 && groups[grps[0]].size()==1)
632 if(newFams.find(grps[0])!=newFams.end())
634 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
635 throw INTERP_KERNEL::Exception(oss.str().c_str());
637 newFams[grps[0]]=(*it).second;
638 std::vector<std::string>& grps2=groups[grps[0]];
639 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
644 if(newFams.find((*it).first)!=newFams.end())
646 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
647 throw INTERP_KERNEL::Exception(oss.str().c_str());
649 newFams[(*it).first]=(*it).second;
657 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
659 * \return the removed groups.
661 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
663 std::vector<std::string> ret;
664 std::map<std::string, std::vector<std::string> > newGrps;
665 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
667 if((*it).second.empty())
668 ret.push_back((*it).first);
670 newGrps[(*it).first]=(*it).second;
677 void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name)
679 std::map<std::string, std::vector<std::string> >::iterator it(_groups.find(name));
680 std::vector<std::string> grps(getGroupsNames());
681 if(it==_groups.end())
683 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
684 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
685 throw INTERP_KERNEL::Exception(oss.str().c_str());
687 const std::vector<std::string> &famsOnGrp((*it).second);
688 std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(name));
689 const DataArrayIdType *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt));
692 MCAuto<DataArrayIdType> vals(famArr->getDifferentValues());
693 MCAuto<DataArrayIdType> famIds2(DataArrayIdType::NewFromStdVector(famIds));
694 MCAuto<DataArrayIdType> idsToKill(famIds2->buildIntersection(vals));
695 if(idsToKill->empty())
697 std::vector<std::string> newFamsOnGrp;
698 for(std::vector<std::string>::const_iterator it=famsOnGrp.begin();it!=famsOnGrp.end();it++)
700 if(!idsToKill->presenceOfValue(getFamilyId(*it)))
701 newFamsOnGrp.push_back(*it);
703 (*it).second=newFamsOnGrp;
707 * Removes a group from \a this mesh.
708 * \param [in] name - the name of the group to remove.
709 * \throw If no group with such a \a name exists.
711 void MEDFileMesh::removeGroup(const std::string& name)
713 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(name);
714 std::vector<std::string> grps(getGroupsNames());
715 if(it==_groups.end())
717 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
718 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
719 throw INTERP_KERNEL::Exception(oss.str().c_str());
725 * Removes a family from \a this mesh.
726 * \param [in] name - the name of the family to remove.
727 * \throw If no family with such a \a name exists.
729 void MEDFileMesh::removeFamily(const std::string& name)
731 std::string oname(name);
732 std::map<std::string, mcIdType >::iterator it=_families.find(oname);
733 std::vector<std::string> fams=getFamiliesNames();
734 if(it==_families.end())
736 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
737 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
738 throw INTERP_KERNEL::Exception(oss.str().c_str());
741 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
743 std::vector<std::string>& v=(*it3).second;
744 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
751 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
752 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
753 * family field whatever its level. This method also suppresses the orphan families.
755 * \return - The list of removed groups names.
757 * \sa MEDFileMesh::removeOrphanFamilies.
759 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
761 removeOrphanFamilies();
762 return removeEmptyGroups();
766 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
767 * 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.
769 * \return - The list of removed families names.
770 * \sa MEDFileMesh::removeOrphanGroups , MEDFileMesh::removeFamiliesReferedByNoGroups
772 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
774 MCAuto<DataArrayIdType> allFamIdsInUse=computeAllFamilyIdsInUse();
775 std::vector<std::string> ret;
776 if(!((DataArrayIdType*)allFamIdsInUse))
778 ret=getFamiliesNames();
779 _families.clear(); _groups.clear();
782 std::map<std::string,mcIdType> famMap;
783 std::map<std::string, std::vector<std::string> > grps(_groups);
784 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
786 if(allFamIdsInUse->presenceOfValue((*it).second))
787 famMap[(*it).first]=(*it).second;
790 ret.push_back((*it).first);
791 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
792 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
794 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
795 std::vector<std::string>& famv=(*it3).second;
796 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
802 { _families=famMap; _groups=grps; }
807 * 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
808 * this family is orphan or not.
810 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
811 * \sa MEDFileMesh::removeOrphanFamilies
813 void MEDFileMesh::removeFamiliesReferedByNoGroups()
815 std::map<std::string,mcIdType> fams;
816 std::set<std::string> sfams;
817 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
818 sfams.insert((*it).first);
819 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
820 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
822 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
823 if(*it!=DFT_FAM_NAME)
824 _families.erase(*it);
828 * 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
829 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
830 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
832 * 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.
834 * \sa MEDFileMesh::removeOrphanFamilies, MEDFileMesh::zipFamilies
836 void MEDFileMesh::rearrangeFamilies()
838 checkOrphanFamilyZero();
839 removeFamiliesReferedByNoGroups();
841 std::vector<int> levels(getNonEmptyLevelsExt());
842 std::set<mcIdType> idsRefed;
843 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
845 idsRefed.insert((*it).second);
848 if(!getGroupsOnFamily((*it).first).empty())
850 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 !";
851 throw INTERP_KERNEL::Exception(oss.str());
855 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
857 const DataArrayIdType *fams(0);
860 fams=getFamilyFieldAtLevel(*it);
862 catch(INTERP_KERNEL::Exception& e) { }
865 std::vector<bool> v(fams->getNumberOfTuples(),false);
866 for(std::set<mcIdType>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
867 fams->switchOnTupleEqualTo(*pt,v);
868 MCAuto<DataArrayIdType> unfetchedIds(DataArrayIdType::BuildListOfSwitchedOff(v));
869 if(!unfetchedIds->empty())
871 MCAuto<DataArrayIdType> newFams(fams->deepCopy());
872 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
873 setFamilyFieldArr(*it,newFams);
876 removeOrphanFamilies();
880 * This method has no impact on existing groups. This method has only impact on families behind the groups.
881 * 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.
882 * 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
883 * having the name of the first family appearing in family definition and with the corresponding family ID.
885 void MEDFileMesh::zipFamilies()
887 checkOrphanFamilyZero();
888 removeFamiliesReferedByNoGroups();
889 std::map< std::set<std::string> , std::vector<std::string> > setOfFamilies;
890 // firstly, store in setOfFamilies as key the common set of groups, and as value the families having such same set of groups
891 for(auto fam : _families)
893 std::vector<std::string> grps( this->getGroupsOnFamily( fam.first ) );
894 std::set<std::string> sgrps(grps.begin(),grps.end());
895 setOfFamilies[sgrps].push_back(fam.first);
898 std::map<std::string, std::vector<std::string> > newGroups(_groups);
899 std::map<std::string,mcIdType> newFams(_families);
900 std::vector<int> levels(getNonEmptyLevelsExt());
901 std::map<mcIdType, std::vector<mcIdType> > famIdsToSubstitute;
902 // iterate on all different set of groups
903 std::set<std::string> familiesToKill;
904 for(auto setOfCommonGrp : setOfFamilies)
906 if( setOfCommonGrp.second.size()<=1 )
908 for(auto fam=setOfCommonGrp.second.begin()+1 ; fam != setOfCommonGrp.second.end() ; fam++)
909 familiesToKill.insert(*fam);
911 // iterate on all different set of groups
912 for(auto setOfCommonGrp : setOfFamilies)
914 if( setOfCommonGrp.second.size()<=1 )
916 std::string newFamName(setOfCommonGrp.second[0]);
917 auto newFamID(_families[newFamName]);
918 for(auto grpToBeModified : setOfCommonGrp.first)
920 std::vector<std::string> newFamiliesForCurGrp(1,newFamName);
921 const std::vector<std::string>& familiesOnCurGrp(_groups[grpToBeModified]);
922 const std::vector<std::string>& familiesToZip(setOfCommonGrp.second);
923 std::for_each(familiesToZip.begin(),familiesToZip.end(),[&famIdsToSubstitute,this,newFamID](const std::string& elt) { famIdsToSubstitute[newFamID].push_back(this->getFamilyId(elt)); });
924 // for each family shared by the current group only keep those not sharing setOfCommonGrp.second
925 std::for_each(familiesOnCurGrp.begin(),familiesOnCurGrp.end(),[&familiesToKill,&newFamiliesForCurGrp](const std::string& elt)
926 { if( familiesToKill.find(elt) == familiesToKill.end() ) { newFamiliesForCurGrp.push_back(elt); } });
927 newGroups[grpToBeModified] = newFamiliesForCurGrp;
929 for(auto familyToKill = setOfCommonGrp.second.begin()+1 ; familyToKill != setOfCommonGrp.second.end(); ++familyToKill)
931 newFams.erase( newFams.find(*familyToKill) );
935 // apply modifications in datastructure
936 for(auto famIdsSubstSession : famIdsToSubstitute)
938 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
940 DataArrayIdType *fams(nullptr);
943 fams=getFamilyFieldAtLevel(*it);
945 catch(INTERP_KERNEL::Exception& e) { }
948 MCAuto<DataArrayIdType> idsToModif(fams->findIdsEqualList(famIdsSubstSession.second.data(),famIdsSubstSession.second.data()+famIdsSubstSession.second.size()));
949 fams->setPartOfValuesSimple3(famIdsSubstSession.first,idsToModif->begin(),idsToModif->end(),0,1,1);
957 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
959 void MEDFileMesh::checkOrphanFamilyZero() const
961 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
963 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
965 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
966 throw INTERP_KERNEL::Exception(oss.str().c_str());
972 * Renames a group in \a this mesh.
973 * \param [in] oldName - a current name of the group to rename.
974 * \param [in] newName - a new group name.
975 * \throw If no group named \a oldName exists in \a this mesh.
976 * \throw If a group named \a newName already exists.
978 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
980 std::string oname(oldName);
981 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
982 std::vector<std::string> grps=getGroupsNames();
983 if(it==_groups.end())
985 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
986 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
987 throw INTERP_KERNEL::Exception(oss.str().c_str());
989 std::string nname(newName);
990 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
991 if(it2!=_groups.end())
993 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
994 throw INTERP_KERNEL::Exception(oss.str().c_str());
996 std::vector<std::string> cpy=(*it).second;
998 _groups[newName]=cpy;
1002 * Changes an id of a family in \a this mesh.
1003 * This method calls changeFamilyIdArr().
1004 * \param [in] oldId - a current id of the family.
1005 * \param [in] newId - a new family id.
1007 void MEDFileMesh::changeFamilyId(mcIdType oldId, mcIdType newId)
1009 changeFamilyIdArr(oldId,newId);
1010 std::map<std::string,mcIdType> fam2;
1011 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1013 if((*it).second==oldId)
1014 fam2[(*it).first]=newId;
1016 fam2[(*it).first]=(*it).second;
1022 * Renames a family in \a this mesh.
1023 * \param [in] oldName - a current name of the family to rename.
1024 * \param [in] newName - a new family name.
1025 * \throw If no family named \a oldName exists in \a this mesh.
1026 * \throw If a family named \a newName already exists.
1028 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
1030 std::string oname(oldName);
1031 std::map<std::string, mcIdType >::iterator it=_families.find(oname);
1032 std::vector<std::string> fams=getFamiliesNames();
1033 if(it==_families.end())
1035 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
1036 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1037 throw INTERP_KERNEL::Exception(oss.str().c_str());
1039 std::string nname(newName);
1040 std::map<std::string, mcIdType >::iterator it2=_families.find(nname);
1041 if(it2!=_families.end())
1043 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
1044 throw INTERP_KERNEL::Exception(oss.str().c_str());
1046 mcIdType cpy=(*it).second;
1047 _families.erase(it);
1048 _families[newName]=cpy;
1049 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
1051 std::vector<std::string>& v=(*it3).second;
1052 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
1059 * Checks if \a this and another mesh contains the same families.
1060 * \param [in] other - the mesh to compare with \a this one.
1061 * \param [in,out] what - an unused parameter.
1062 * \return bool - \c true if number of families and their ids are the same in the two
1063 * meshes. Families with the id == \c 0 are not considered.
1065 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
1067 if(_families==other->_families)
1069 std::map<std::string,mcIdType> fam0;
1070 std::map<std::string,mcIdType> fam1;
1071 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1073 fam0[(*it).first]=(*it).second;
1074 for(std::map<std::string,mcIdType>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
1076 fam1[(*it).first]=(*it).second;
1081 * Checks if \a this and another mesh contains the same groups.
1082 * \param [in] other - the mesh to compare with \a this one.
1083 * \param [in,out] what - a string describing a difference of groups of the two meshes
1084 * in case if this method returns \c false.
1085 * \return bool - \c true if number of groups and families constituting them are the
1086 * same in the two meshes.
1088 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
1090 if(_groups==other->_groups)
1093 std::size_t sz=_groups.size();
1094 if(sz!=other->_groups.size())
1096 what="Groups differ because not same number !\n";
1101 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
1102 for(std::size_t i=0;i<sz && ret;i++,it1++)
1104 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
1105 if(it2!=other->_groups.end())
1107 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
1108 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1114 what="A group in first mesh exists not in other !\n";
1120 std::ostringstream oss; oss << "Groups description differs :\n";
1121 oss << "First group description :\n";
1122 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1124 oss << " Group \"" << (*it).first << "\" on following families :\n";
1125 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1126 oss << " \"" << *it2 << "\n";
1128 oss << "Second group description :\n";
1129 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1131 oss << " Group \"" << (*it).first << "\" on following families :\n";
1132 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1133 oss << " \"" << *it2 << "\n";
1141 * Checks if a group with a given name exists in \a this mesh.
1142 * \param [in] groupName - the group name.
1143 * \return bool - \c true the group \a groupName exists in \a this mesh.
1145 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1147 std::string grpName(groupName);
1148 return _groups.find(grpName)!=_groups.end();
1152 * Checks if a family with a given id exists in \a this mesh.
1153 * \param [in] famId - the family id.
1154 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1156 bool MEDFileMesh::existsFamily(mcIdType famId) const
1158 for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1159 if((*it2).second==famId)
1165 * Checks if a family with a given name exists in \a this mesh.
1166 * \param [in] familyName - the family name.
1167 * \return bool - \c true the family \a familyName exists in \a this mesh.
1169 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1171 std::string fname(familyName);
1172 return _families.find(fname)!=_families.end();
1176 * Sets an id of a family.
1177 * \param [in] familyName - the family name.
1178 * \param [in] id - a new id of the family.
1180 void MEDFileMesh::setFamilyId(const std::string& familyName, mcIdType id)
1182 std::string fname(familyName);
1183 _families[fname]=id;
1186 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, mcIdType id)
1188 std::string fname(familyName);
1189 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1190 if((*it).second==id)
1192 if((*it).first!=familyName)
1194 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1195 throw INTERP_KERNEL::Exception(oss.str().c_str());
1198 _families[fname]=id;
1202 * Adds a family to \a this mesh.
1203 * \param [in] familyName - a name of the family.
1204 * \param [in] famId - an id of the family.
1205 * \throw If a family with the same name or id already exists in \a this mesh.
1207 void MEDFileMesh::addFamily(const std::string& familyName, mcIdType famId)
1209 std::string fname(familyName);
1210 std::map<std::string,mcIdType>::const_iterator it=_families.find(fname);
1211 if(it==_families.end())
1213 for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1214 if((*it2).second==famId)
1216 std::ostringstream oss;
1217 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1218 throw INTERP_KERNEL::Exception(oss.str().c_str());
1220 _families[fname]=famId;
1224 if((*it).second!=famId)
1226 std::ostringstream oss;
1227 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1228 throw INTERP_KERNEL::Exception(oss.str().c_str());
1234 * Creates a group including all mesh entities of given dimension.
1235 * \warning This method does \b not guarantee that the created group includes mesh
1236 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1237 * present in family fields of different dimensions. To assure this, call
1238 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1239 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1241 * \param [in] groupName - a name of the new group.
1242 * \throw If a group named \a groupName already exists.
1243 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1244 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1246 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1248 std::string grpName(groupName);
1249 std::vector<int> levs=getNonEmptyLevelsExt();
1250 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1252 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1253 oss << "Available relative ext levels are : ";
1254 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1255 throw INTERP_KERNEL::Exception(oss.str().c_str());
1257 if(existsGroup(groupName))
1259 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1260 oss << "Already existing groups are : ";
1261 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1262 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1263 throw INTERP_KERNEL::Exception(oss.str().c_str());
1265 const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1267 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1268 MCAuto<DataArrayIdType> famIds=fieldFamIds->getDifferentValues();
1269 std::vector<std::string> familiesOnWholeGroup;
1270 for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
1273 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1275 _groups[grpName]=familiesOnWholeGroup;
1279 * Ensures that given family ids do not present in family fields of dimensions different
1280 * than given ones. If a family id is present in the family fields of dimensions different
1281 * than the given ones, a new family is created and the whole data is updated accordingly.
1282 * \param [in] famIds - a sequence of family ids to check.
1283 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1284 * famIds should exclusively belong.
1285 * \return bool - \c true if no modification is done in \a this mesh by this method.
1287 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<mcIdType>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1289 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1290 std::vector<int> levs=getNonEmptyLevelsExt();
1291 std::set<int> levs2(levs.begin(),levs.end());
1292 std::vector<int> levsToTest;
1293 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1294 std::set<mcIdType> famIds2(famIds.begin(),famIds.end());
1296 mcIdType maxFamId=1;
1297 if(!_families.empty())
1298 maxFamId=getMaxFamilyId()+1;
1299 std::vector<std::string> allFams=getFamiliesNames();
1300 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1302 const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(*it);
1305 MCAuto<DataArrayIdType> famIds3=fieldFamIds->getDifferentValues();
1306 std::vector<mcIdType> tmp;
1307 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<mcIdType> >(tmp));
1308 for(std::vector<mcIdType>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1311 std::string famName=getFamilyNameGivenId(*it2);
1312 std::ostringstream oss; oss << "Family_" << maxFamId;
1313 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1314 addFamilyOnAllGroupsHaving(famName,zeName);
1315 _families[zeName]=maxFamId;
1316 (const_cast<DataArrayIdType *>(fieldFamIds))->changeValue(*it2,maxFamId);
1325 * Adds a family to a given group in \a this mesh. If the group with a given name does
1326 * not exist, it is created.
1327 * \param [in] grpName - the name of the group to add the family in.
1328 * \param [in] famName - the name of the family to add to the group named \a grpName.
1329 * \throw If \a grpName or \a famName is an empty string.
1330 * \throw If no family named \a famName is present in \a this mesh.
1332 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1334 std::string grpn(grpName);
1335 std::string famn(famName);
1336 if(grpn.empty() || famn.empty())
1337 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1338 std::vector<std::string> fams=getFamiliesNames();
1339 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1341 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1342 oss << "Create this family or choose an existing one ! Existing fams are : ";
1343 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1344 throw INTERP_KERNEL::Exception(oss.str().c_str());
1346 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1347 if(it==_groups.end())
1349 _groups[grpn].push_back(famn);
1353 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1354 if(it2==(*it).second.end())
1355 (*it).second.push_back(famn);
1360 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1361 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1362 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1364 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1366 std::string famNameCpp(famName);
1367 std::string otherCpp(otherFamName);
1368 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1370 std::vector<std::string>& v=(*it).second;
1371 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1373 v.push_back(otherCpp);
1378 void MEDFileMesh::checkNoGroupClash(const DataArrayIdType *famArr, const std::string& grpName) const
1380 std::vector<std::string> grpsNames(getGroupsNames());
1381 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
1383 std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(grpName));
1384 if(famArr->presenceOfValue(famIds))
1386 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
1387 throw INTERP_KERNEL::Exception(oss.str().c_str());
1392 * \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).
1393 * \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)
1395 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayIdType *ids, DataArrayIdType *famArr)
1398 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1399 std::string grpName(ids->getName());
1401 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1402 ids->checkStrictlyMonotonic(true);
1403 checkNoGroupClash(famArr,grpName);
1404 MCAuto<DataArrayIdType> famArrTmp; famArrTmp.takeRef(famArr);
1405 std::list< MCAuto<DataArrayIdType> > allFamIds(getAllNonNullFamilyIds());
1406 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1407 MCAuto<DataArrayIdType> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1408 MCAuto<DataArrayIdType> diffFamIds=famIds->getDifferentValues();
1409 std::vector<mcIdType> familyIds;
1410 std::vector< MCAuto<DataArrayIdType> > idsPerfamiliyIds;
1411 mcIdType maxVal=getTheMaxAbsFamilyId()+1;
1412 std::map<std::string,mcIdType> families(_families);
1413 std::map<std::string, std::vector<std::string> > groups(_groups);
1414 std::vector<std::string> fams;
1415 bool created(false);
1416 for(const mcIdType *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1418 MCAuto<DataArrayIdType> ids2Tmp=famIds->findIdsEqual(*famId);
1419 MCAuto<DataArrayIdType> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1420 MCAuto<DataArrayIdType> ids1=famArr->findIdsEqual(*famId);
1421 MCAuto<DataArrayIdType> ret0(ids1->buildSubstractionOptimized(ids2));
1424 bool isFamPresent=false;
1425 for(std::list< MCAuto<DataArrayIdType> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1426 isFamPresent=(*itl)->presenceOfValue(*famId);
1427 if(!isFamPresent && *famId!=0)
1428 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1431 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1432 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1433 fams.push_back(locFamName);
1434 if(existsFamily(*famId))
1436 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1437 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1440 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1444 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1445 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1446 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1447 if(existsFamily(*famId))
1449 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1450 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1455 for(std::size_t i=0;i<familyIds.size();i++)
1457 DataArrayIdType *da=idsPerfamiliyIds[i];
1458 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1461 std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
1462 if(itt!=groups.end())
1464 std::vector<std::string>& famsOnGrp((*itt).second);
1465 famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
1468 groups[grpName]=fams;
1472 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1474 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1477 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1479 std::string fam(familyNameToChange);
1480 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1482 std::vector<std::string>& fams((*it).second);
1483 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1487 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1493 * Returns a name of the family having a given id or, if no such a family exists, creates
1494 * a new uniquely named family and returns its name.
1495 * \param [in] id - the id of the family whose name is required.
1496 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1497 * \return std::string - the name of the existing or the created family.
1498 * \throw If it is not possible to create a unique family name.
1500 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(mcIdType id, bool& created)
1502 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1506 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1507 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1508 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1509 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1511 * This method will throws an exception if it is not possible to create a unique family name.
1513 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,mcIdType>& families, mcIdType id, bool& created)
1515 std::vector<std::string> famAlreadyExisting(families.size());
1517 for(std::map<std::string,mcIdType>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1519 if((*it).second!=id)
1521 famAlreadyExisting[ii]=(*it).first;
1530 std::ostringstream oss; oss << "Family_" << id;
1531 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1537 * Sets names and ids of all families in \a this mesh.
1538 * \param [in] info - a map of a family name to a family id.
1540 void MEDFileMesh::setFamilyInfo(const std::map<std::string,mcIdType>& info)
1546 * Sets names of all groups and families constituting them in \a this mesh.
1547 * \param [in] info - a map of a group name to a vector of names of families
1548 * constituting the group.
1550 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1556 * Returns an id of the family having a given name.
1557 * \param [in] name - the name of the family of interest.
1558 * \return mcIdType - the id of the family of interest.
1559 * \throw If no family with such a \a name exists.
1561 mcIdType MEDFileMesh::getFamilyId(const std::string& name) const
1563 std::map<std::string, mcIdType>::const_iterator it=_families.find(name);
1564 if(it==_families.end())
1566 std::vector<std::string> fams(getFamiliesNames());
1567 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1568 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1569 throw INTERP_KERNEL::Exception(oss.str().c_str());
1571 return (*it).second;
1575 * Returns ids of the families having given names.
1576 * \param [in] fams - a sequence of the names of families of interest.
1577 * \return std::vector<mcIdType> - a sequence of the ids of families of interest.
1578 * \throw If \a fams contains a name of an inexistent family.
1580 std::vector<mcIdType> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1582 std::vector<mcIdType> ret(fams.size());
1584 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1586 std::map<std::string, mcIdType>::const_iterator it2=_families.find(*it);
1587 if(it2==_families.end())
1589 std::vector<std::string> fams2=getFamiliesNames();
1590 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1591 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1592 throw INTERP_KERNEL::Exception(oss.str().c_str());
1594 ret[i]=(*it2).second;
1600 * Returns a maximal abs(id) of families in \a this mesh.
1601 * \return mcIdType - the maximal norm of family id.
1602 * \throw If there are no families in \a this mesh.
1604 mcIdType MEDFileMesh::getMaxAbsFamilyId() const
1606 if(_families.empty())
1607 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1608 mcIdType ret=-std::numeric_limits<mcIdType>::max();
1609 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1611 ret=std::max(std::abs((*it).second),ret);
1617 * Returns a maximal id of families in \a this mesh.
1618 * \return mcIdType - the maximal family id.
1619 * \throw If there are no families in \a this mesh.
1621 mcIdType MEDFileMesh::getMaxFamilyId() const
1623 if(_families.empty())
1624 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1625 mcIdType ret=-std::numeric_limits<mcIdType>::max();
1626 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1628 ret=std::max((*it).second,ret);
1634 * Returns a minimal id of families in \a this mesh.
1635 * \return mcIdType - the minimal family id.
1636 * \throw If there are no families in \a this mesh.
1638 mcIdType MEDFileMesh::getMinFamilyId() const
1640 if(_families.empty())
1641 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1642 mcIdType ret=std::numeric_limits<mcIdType>::max();
1643 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1645 ret=std::min((*it).second,ret);
1651 * Returns a maximal id of families in \a this mesh. Not only named families are
1652 * considered but all family fields as well.
1653 * \return mcIdType - the maximal family id.
1655 mcIdType MEDFileMesh::getTheMaxAbsFamilyId() const
1657 mcIdType m1=-std::numeric_limits<mcIdType>::max();
1658 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1659 m1=std::max(std::abs((*it).second),m1);
1660 mcIdType m2=getMaxAbsFamilyIdInArrays();
1661 return std::max(m1,m2);
1665 * Returns a maximal id of families in \a this mesh. Not only named families are
1666 * considered but all family fields as well.
1667 * \return mcIdType - the maximal family id.
1669 mcIdType MEDFileMesh::getTheMaxFamilyId() const
1671 mcIdType m1=-std::numeric_limits<mcIdType>::max();
1672 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1673 m1=std::max((*it).second,m1);
1674 mcIdType m2=getMaxFamilyIdInArrays();
1675 return std::max(m1,m2);
1679 * Returns a minimal id of families in \a this mesh. Not only named families are
1680 * considered but all family fields as well.
1681 * \return mcIdType - the minimal family id.
1683 mcIdType MEDFileMesh::getTheMinFamilyId() const
1685 mcIdType m1=std::numeric_limits<mcIdType>::max();
1686 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1687 m1=std::min((*it).second,m1);
1688 mcIdType m2=getMinFamilyIdInArrays();
1689 return std::min(m1,m2);
1693 * This method only considers the maps. The contain of family array is ignored here.
1695 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1697 DataArrayIdType *MEDFileMesh::getAllFamiliesIdsReferenced() const
1699 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
1700 std::set<mcIdType> v;
1701 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1702 v.insert((*it).second);
1703 ret->alloc((mcIdType)v.size(),1);
1704 std::copy(v.begin(),v.end(),ret->getPointer());
1709 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1711 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1713 DataArrayIdType *MEDFileMesh::computeAllFamilyIdsInUse() const
1715 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1716 MCAuto<DataArrayIdType> ret;
1717 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1719 const DataArrayIdType *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1720 MCAuto<DataArrayIdType> dv=arr->getDifferentValues();
1721 if((DataArrayIdType *) ret)
1722 ret=dv->buildUnion(ret);
1730 * true is returned if no modification has been needed. false if family
1731 * renumbering has been needed.
1733 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1735 std::vector<int> levs=getNonEmptyLevelsExt();
1736 std::set<mcIdType> allFamIds;
1737 mcIdType maxId=getMaxFamilyId()+1;
1738 std::map<int,std::vector<mcIdType> > famIdsToRenum;
1739 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1741 const DataArrayIdType *fam=getFamilyFieldAtLevel(*it);
1744 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1745 std::set<mcIdType> r2;
1746 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1748 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1749 std::set<mcIdType> r3;
1750 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1753 if(famIdsToRenum.empty())
1755 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1756 for(std::map<int,std::vector<mcIdType> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1758 DataArrayIdType *fam=const_cast<DataArrayIdType *>(getFamilyFieldAtLevel((*it2).first));
1759 mcIdType *famIdsToChange=fam->getPointer();
1760 std::map<mcIdType,mcIdType> ren;
1761 for(std::vector<mcIdType>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1763 if(allIds->presenceOfValue(*it3))
1765 std::string famName=getFamilyNameGivenId(*it3);
1766 std::vector<std::string> grps=getGroupsOnFamily(famName);
1769 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1770 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1771 addFamilyOnGrp((*it4),newFam);
1774 MCAuto<DataArrayIdType> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1775 for(const mcIdType *id=ids->begin();id!=ids->end();id++)
1776 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1782 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1783 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1784 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1785 * This method will throw an exception if a same family id is detected in different level.
1786 * \warning This policy is the opposite of those in MED file documentation ...
1788 void MEDFileMesh::normalizeFamIdsTrio()
1790 ensureDifferentFamIdsPerLevel();
1791 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1792 std::vector<int> levs=getNonEmptyLevelsExt();
1793 std::set<int> levsS(levs.begin(),levs.end());
1794 std::set<std::string> famsFetched;
1795 std::map<std::string,mcIdType> families;
1796 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1799 const DataArrayIdType *fam=getFamilyFieldAtLevel(0);
1803 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1804 std::map<mcIdType,mcIdType> ren;
1805 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
1807 mcIdType nbOfTuples=fam->getNumberOfTuples();
1808 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1809 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1811 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1813 if(allIds->presenceOfValue(*it))
1815 std::string famName=getFamilyNameGivenId(*it);
1816 families[famName]=ren[*it];
1817 famsFetched.insert(famName);
1822 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1825 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
1829 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1830 std::map<mcIdType,mcIdType> ren;
1831 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
1833 mcIdType nbOfTuples=fam->getNumberOfTuples();
1834 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1835 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1837 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1839 if(allIds->presenceOfValue(*it))
1841 std::string famName=getFamilyNameGivenId(*it);
1842 families[famName]=ren[*it];
1843 famsFetched.insert(famName);
1848 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1850 DataArrayIdType *fam=const_cast<DataArrayIdType*>(getFamilyFieldAtLevel(*it2));
1853 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1854 fam->fillWithZero();
1855 for(const mcIdType *it3=tmp->begin();it3!=tmp->end();it3++)
1856 if(allIds->presenceOfValue(*it3))
1858 std::string famName=getFamilyNameGivenId(*it3);
1859 families[famName]=0;
1860 famsFetched.insert(famName);
1865 std::vector<std::string> allFams=getFamiliesNames();
1866 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1867 std::set<std::string> unFetchedIds;
1868 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1869 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1870 families[*it4]=_families[*it4];
1875 * This method normalizes fam id with the following policy.
1876 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1877 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1878 * This method will throw an exception if a same family id is detected in different level.
1880 void MEDFileMesh::normalizeFamIdsMEDFile()
1882 ensureDifferentFamIdsPerLevel();
1883 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1884 std::vector<int> levs=getNonEmptyLevelsExt();
1885 std::set<int> levsS(levs.begin(),levs.end());
1886 std::set<std::string> famsFetched;
1887 std::map<std::string,mcIdType> families;
1889 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1892 const DataArrayIdType *fam=getFamilyFieldAtLevel(1);
1895 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1896 std::map<mcIdType,mcIdType> ren;
1897 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
1899 mcIdType nbOfTuples=fam->getNumberOfTuples();
1900 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1901 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1903 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1905 if(allIds->presenceOfValue(*it))
1907 std::string famName=getFamilyNameGivenId(*it);
1908 families[famName]=ren[*it];
1909 famsFetched.insert(famName);
1915 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1917 const DataArrayIdType *fam=getFamilyFieldAtLevel(*it2);
1920 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1921 std::map<mcIdType,mcIdType> ren;
1922 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
1924 mcIdType nbOfTuples=fam->getNumberOfTuples();
1925 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1926 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1928 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1930 if(allIds->presenceOfValue(*it))
1932 std::string famName=getFamilyNameGivenId(*it);
1933 families[famName]=ren[*it];
1934 famsFetched.insert(famName);
1940 std::vector<std::string> allFams=getFamiliesNames();
1941 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1942 std::set<std::string> unFetchedIds;
1943 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1944 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1945 families[*it4]=_families[*it4];
1950 * Returns a name of the family by its id. If there are several families having the given
1951 * id, the name first in lexical order is returned.
1952 * \param [in] id - the id of the family whose name is required.
1953 * \return std::string - the name of the found family.
1954 * \throw If no family with the given \a id exists.
1956 std::string MEDFileMesh::getFamilyNameGivenId(mcIdType id) const
1958 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1959 if((*it).second==id)
1961 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1962 throw INTERP_KERNEL::Exception(oss.str().c_str());
1966 * Returns a string describing \a this mesh. This description includes the mesh name and
1967 * the mesh description string.
1968 * \return std::string - the mesh information string.
1970 std::string MEDFileMesh::simpleRepr() const
1972 std::ostringstream oss;
1973 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1974 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1975 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1980 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1981 * an empty one is created.
1983 DataArrayIdType *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1985 DataArrayIdType *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1988 MCAuto<DataArrayIdType> arr(DataArrayIdType::New());
1989 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1990 arr->fillWithZero();
1991 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1992 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1996 * Returns ids of mesh entities contained in a given group of a given dimension.
1997 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1999 * \param [in] grp - the name of the group of interest.
2000 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2001 * returned instead of ids.
2002 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2003 * numbers, if available and required, of mesh entities of the group. The caller
2004 * is to delete this array using decrRef() as it is no more needed.
2005 * \throw If the name of a nonexistent group is specified.
2006 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2008 DataArrayIdType *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2010 std::vector<std::string> tmp(1);
2012 DataArrayIdType *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
2018 * Returns ids of mesh entities contained in given groups of a given dimension.
2019 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2021 * \param [in] grps - the names of the groups of interest.
2022 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2023 * returned instead of ids.
2024 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2025 * numbers, if available and required, of mesh entities of the groups. The caller
2026 * is to delete this array using decrRef() as it is no more needed.
2027 * \throw If the name of a nonexistent group is present in \a grps.
2028 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2030 DataArrayIdType *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2032 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2033 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
2037 * Returns ids of mesh entities contained in a given family of a given dimension.
2038 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2040 * \param [in] fam - the name of the family of interest.
2041 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2042 * returned instead of ids.
2043 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2044 * numbers, if available and required, of mesh entities of the family. The caller
2045 * is to delete this array using decrRef() as it is no more needed.
2046 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2048 DataArrayIdType *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2050 std::vector<std::string> tmp(1);
2052 DataArrayIdType *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
2058 * Returns ids of nodes contained in a given group.
2059 * \param [in] grp - the name of the group of interest.
2060 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2061 * returned instead of ids.
2062 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2063 * numbers, if available and required, of nodes of the group. The caller
2064 * is to delete this array using decrRef() as it is no more needed.
2065 * \throw If the name of a nonexistent group is specified.
2066 * \throw If the family field is missing for nodes.
2068 DataArrayIdType *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
2070 std::vector<std::string> tmp(1);
2072 DataArrayIdType *ret=getNodeGroupsArr(tmp,renum);
2078 * Returns ids of nodes contained in given groups.
2079 * \param [in] grps - the names of the groups of interest.
2080 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2081 * returned instead of ids.
2082 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2083 * numbers, if available and required, of nodes of the groups. The caller
2084 * is to delete this array using decrRef() as it is no more needed.
2085 * \throw If the name of a nonexistent group is present in \a grps.
2086 * \throw If the family field is missing for nodes.
2088 DataArrayIdType *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
2090 return getGroupsArr(1,grps,renum);
2094 * Returns ids of nodes contained in a given group.
2095 * \param [in] grp - the name of the group of interest.
2096 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2097 * returned instead of ids.
2098 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2099 * numbers, if available and required, of nodes of the group. The caller
2100 * is to delete this array using decrRef() as it is no more needed.
2101 * \throw If the name of a nonexistent group is specified.
2102 * \throw If the family field is missing for nodes.
2104 DataArrayIdType *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
2106 std::vector<std::string> tmp(1);
2108 DataArrayIdType *ret=getNodeFamiliesArr(tmp,renum);
2114 * Returns ids of nodes contained in given families.
2115 * \param [in] fams - the names of the families of interest.
2116 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2117 * returned instead of ids.
2118 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2119 * numbers, if available and required, of nodes of the families. The caller
2120 * is to delete this array using decrRef() as it is no more needed.
2121 * \throw If the family field is missing for nodes.
2123 DataArrayIdType *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2125 return getFamiliesArr(1,fams,renum);
2129 * Adds groups of given dimension and creates corresponding families and family fields
2130 * given ids of mesh entities of each group.
2131 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2132 * \param [in] grps - a sequence of arrays of ids each describing a group.
2133 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2135 * \throw If names of some groups in \a grps are equal.
2136 * \throw If \a grps includes a group with an empty name.
2137 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2138 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2140 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayIdType *>& grps, bool renum)
2144 std::set<std::string> grpsName;
2145 std::vector<std::string> grpsName2(grps.size());
2148 for(std::vector<const DataArrayIdType *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2150 grpsName.insert((*it)->getName());
2151 grpsName2[i]=(*it)->getName();
2153 if(grpsName.size()!=grps.size())
2154 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2155 if(grpsName.find(std::string(""))!=grpsName.end())
2156 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2157 mcIdType sz=getSizeAtLevel(meshDimRelToMaxExt);
2158 MCAuto<DataArrayIdType> fam;
2159 std::vector< std::vector<mcIdType> > fidsOfGroups;
2162 fam=DataArrayIdType::MakePartition(grps,sz,fidsOfGroups);
2166 std::vector< MCAuto<DataArrayIdType> > grps2(grps.size());
2167 for(unsigned int ii=0;ii<grps.size();ii++)
2169 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2170 grps2[ii]->setName(grps[ii]->getName());
2172 std::vector<const DataArrayIdType *> grps3(grps2.begin(),grps2.end());
2173 fam=DataArrayIdType::MakePartition(grps3,sz,fidsOfGroups);
2176 if(!_families.empty())
2177 offset=getMaxAbsFamilyId()+1;
2178 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2179 MCAuto<DataArrayIdType> ids=fam->getDifferentValues();
2180 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2181 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2185 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2186 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2187 * For the moment, the two last input parameters are not taken into account.
2189 void MEDFileMesh::appendFamilyEntries(const DataArrayIdType *famIds, const std::vector< std::vector<mcIdType> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2191 std::map<mcIdType,std::string> famInv;
2192 for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
2194 std::ostringstream oss;
2195 oss << "Family_" << (*it);
2196 _families[oss.str()]=(*it);
2197 famInv[*it]=oss.str();
2200 for(std::vector< std::vector<mcIdType> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2202 for(std::vector<mcIdType>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2204 _groups[grpNames[i]].push_back(famInv[*it2]);
2209 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2211 std::vector<int> levs(getNonEmptyLevels());
2212 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2213 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2215 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2216 ret.insert(ret.end(),elts.begin(),elts.end());
2222 * \sa getAllDistributionOfTypes
2224 std::vector<mcIdType> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2226 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2227 return mLev->getDistributionOfTypes();
2230 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2232 loadLL(fid,mName,dt,it,mrs);
2233 loadJointsFromFile(fid);
2234 loadEquivalences(fid);
2237 void MEDFileMesh::TranslateFamilyIds(mcIdType offset, DataArrayIdType *famArr, std::vector< std::vector<mcIdType> >& famIdsPerGrp)
2239 famArr->applyLin(offset>0?1:-1,offset,0);
2240 for(std::vector< std::vector<mcIdType> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2243 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<mcIdType>());
2244 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<mcIdType>(),offset));
2249 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2250 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2251 * If this method fails to find such a name it will throw an exception.
2253 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2256 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2259 std::size_t len=nameTry.length();
2260 for(std::size_t ii=1;ii<len;ii++)
2262 std::string tmp=nameTry.substr(ii,len-ii);
2263 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2269 for(char i=1;i<30;i++)
2271 std::string tmp1(nameTry.at(0),i);
2273 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2279 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2281 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2283 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2286 mcIdType MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<mcIdType>& code, mcIdType strt)
2288 std::size_t nbOfChunks=code.size()/3;
2289 if(code.size()%3!=0)
2290 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2292 for(std::size_t i=0;i<nbOfChunks;i++)
2301 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2302 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2303 * If _name is not empty and that 'm' has the same name nothing is done.
2304 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2306 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2309 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2314 std::string name(m->getName());
2319 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2320 oss << name << "' ! Names must match !";
2321 throw INTERP_KERNEL::Exception(oss.str().c_str());
2325 if(_desc_name.empty())
2326 _desc_name=m->getDescription();
2329 std::string name(m->getDescription());
2332 if(_desc_name!=name)
2334 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2335 oss << name << "' ! Names must match !";
2336 throw INTERP_KERNEL::Exception(oss.str().c_str());
2342 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2344 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2345 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
2347 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2348 oss << " - Groups lying on this family : ";
2349 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2350 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2351 oss << std::endl << std::endl;
2356 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2357 * file. The mesh to load is specified by its name and numbers of a time step and an
2359 * \param [in] fileName - the name of MED file to read.
2360 * \param [in] mName - the name of the mesh to read.
2361 * \param [in] dt - the number of a time step.
2362 * \param [in] it - the number of an iteration.
2363 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2364 * mesh using decrRef() as it is no more needed.
2365 * \throw If the file is not readable.
2366 * \throw If there is no mesh with given attributes in the file.
2367 * \throw If the mesh in the file is not an unstructured one.
2369 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2371 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2372 return New(fid,mName,dt,it,mrs);
2375 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2377 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2381 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2382 * file. The first mesh in the file is loaded.
2383 * \param [in] fileName - the name of MED file to read.
2384 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2385 * mesh using decrRef() as it is no more needed.
2386 * \throw If the file is not readable.
2387 * \throw If there is no meshes in the file.
2388 * \throw If the mesh in the file is not an unstructured one.
2390 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2392 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2393 return New(fid,mrs);
2397 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2399 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2402 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2403 throw INTERP_KERNEL::Exception(oss.str().c_str());
2406 MEDCoupling::MEDCouplingMeshType meshType;
2408 MEDCoupling::MEDCouplingAxisType dummy3;
2409 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2410 return T::New(fid,ms.front(),dt,it,mrs);
2413 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2415 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2419 * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2420 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2422 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2425 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2426 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2427 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2428 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2430 m2D->setCoords(m3D->getCoords());
2431 ret->setMeshAtLevel(0,m3D);
2432 ret->setMeshAtLevel(-1,m2D);
2433 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<med_int>::max()-mem->get2DCellIdForExtrusion());
2438 * Returns an empty instance of MEDFileUMesh.
2439 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2440 * mesh using decrRef() as it is no more needed.
2442 MEDFileUMesh *MEDFileUMesh::New()
2444 return new MEDFileUMesh;
2448 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2449 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2450 * \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.
2451 * 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
2452 * at most the memory consumtion.
2454 * \param [in] fileName - the name of the file.
2455 * \param [in] mName - the name of the mesh to be read.
2456 * \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.
2457 * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
2458 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2459 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2460 * \param [in] mrs - the request for what to be loaded.
2461 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2463 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)
2465 MEDFileUtilities::CheckFileForRead(fileName);
2466 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2467 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2471 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2472 * This method is \b NOT wrapped into python.
2474 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)
2476 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2477 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2481 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2483 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2484 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2488 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2490 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2491 ret.push_back((const DataArrayDouble*)_coords);
2492 ret.push_back((const DataArrayIdType *)_fam_coords);
2493 ret.push_back((const DataArrayIdType *)_num_coords);
2494 ret.push_back((const DataArrayIdType *)_global_num_coords);
2495 ret.push_back((const DataArrayIdType *)_rev_num_coords);
2496 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2497 ret.push_back((const PartDefinition *)_part_coords);
2498 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2499 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2500 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2501 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2505 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2507 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2511 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2513 return new MEDFileUMesh;
2516 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2518 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2519 ret->deepCpyEquivalences(*this);
2520 if(_coords.isNotNull())
2521 ret->_coords=_coords->deepCopy();
2522 if(_fam_coords.isNotNull())
2523 ret->_fam_coords=_fam_coords->deepCopy();
2524 if(_num_coords.isNotNull())
2525 ret->_num_coords=_num_coords->deepCopy();
2526 if(_global_num_coords.isNotNull())
2527 ret->_global_num_coords=_global_num_coords->deepCopy();
2528 if(_rev_num_coords.isNotNull())
2529 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2530 if(_name_coords.isNotNull())
2531 ret->_name_coords=_name_coords->deepCopy();
2533 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2535 if((const MEDFileUMeshSplitL1 *)(*it))
2536 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2538 if((const PartDefinition*)_part_coords)
2539 ret->_part_coords=_part_coords->deepCopy();
2544 * Checks if \a this and another mesh are equal.
2545 * \param [in] other - the mesh to compare with.
2546 * \param [in] eps - a precision used to compare real values.
2547 * \param [in,out] what - the string returning description of unequal data.
2548 * \return bool - \c true if the meshes are equal, \c false, else.
2550 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2552 if(!MEDFileMesh::isEqual(other,eps,what))
2554 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2557 what="Mesh types differ ! This is unstructured and other is NOT !";
2560 clearNonDiscrAttributes();
2561 otherC->clearNonDiscrAttributes();
2562 const DataArrayDouble *coo1=_coords;
2563 const DataArrayDouble *coo2=otherC->_coords;
2564 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2566 what="Mismatch of coordinates ! One is defined and not other !";
2571 bool ret=coo1->isEqual(*coo2,eps);
2574 what="Coords differ !";
2579 const DataArrayIdType *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2580 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2582 what="Mismatch of families arr on nodes ! One is defined and not other !";
2587 bool ret=famc1->isEqual(*famc2);
2590 what="Families arr on node differ !";
2596 const DataArrayIdType *numc1(_num_coords),*numc2(otherC->_num_coords);
2597 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2599 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2604 bool ret=numc1->isEqual(*numc2);
2607 what="Numbering arr on node differ !";
2613 const DataArrayIdType *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2614 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2616 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2621 bool ret=gnumc1->isEqual(*gnumc2);
2624 what="Global numbering arr on node differ !";
2630 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2631 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2633 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2638 bool ret=namec1->isEqual(*namec2);
2641 what="Names arr on node differ !";
2646 if(_ms.size()!=otherC->_ms.size())
2648 what="Number of levels differs !";
2651 std::size_t sz=_ms.size();
2652 for(std::size_t i=0;i<sz;i++)
2654 const MEDFileUMeshSplitL1 *s1=_ms[i];
2655 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2656 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2658 what="Mismatch of presence of sub levels !";
2663 bool ret=s1->isEqual(s2,eps,what);
2668 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2671 if((!pd0 && pd1) || (pd0 && !pd1))
2673 what=std::string("node part def is defined only for one among this or other !");
2676 return pd0->isEqual(pd1,what);
2680 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2681 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2682 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2683 * \throw if internal family array is inconsistent
2684 * \sa checkSMESHConsistency()
2686 void MEDFileUMesh::checkConsistency() const
2688 if(!_coords || !_coords->isAllocated())
2691 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2693 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2694 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2695 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2699 mcIdType nbCoo = _coords->getNumberOfTuples();
2700 if (_fam_coords.isNotNull())
2701 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2702 if (_num_coords.isNotNull())
2704 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2706 mcIdType maxValue=_num_coords->getMaxValue(pos);
2707 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2708 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2710 if (_global_num_coords.isNotNull())
2712 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2714 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2715 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2716 if (_num_coords && !_num_coords->hasUniqueValues())
2717 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2719 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2720 // Now sub part check:
2721 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2722 it != _ms.end(); it++)
2723 (*it)->checkConsistency();
2728 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2729 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2730 * entities as it likes), or non overlapping between all sub-levels.
2731 * \throw if the condition above is not respected
2733 void MEDFileUMesh::checkSMESHConsistency() const
2736 // For all sub-levels, numbering is either always null or with void intersection:
2739 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2740 std::vector< const DataArrayIdType * > v;
2741 bool voidOrNot = ((*it)->_num == 0);
2742 for (it++; it != _ms.end(); it++)
2743 if( ((*it)->_num == 0) != voidOrNot )
2744 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2745 else if (!voidOrNot)
2746 v.push_back((*it)->_num);
2749 // don't forget the 1st one:
2750 v.push_back(_ms[0]->_num);
2751 MCAuto<DataArrayIdType> inter = DataArrayIdType::BuildIntersection(v);
2752 if (inter->getNumberOfTuples())
2753 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2759 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2760 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2762 void MEDFileUMesh::clearNodeAndCellNumbers()
2764 _num_coords.nullify();
2765 _rev_num_coords.nullify();
2766 _global_num_coords.nullify();
2767 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2769 (*it)->_num.nullify();
2770 (*it)->_rev_num.nullify();
2771 (*it)->_global_num.nullify();
2776 * Clears redundant attributes of incorporated data arrays.
2778 void MEDFileUMesh::clearNonDiscrAttributes() const
2780 MEDFileMesh::clearNonDiscrAttributes();
2781 if(_coords.isNotNull())
2782 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2783 if(_fam_coords.isNotNull())
2784 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2785 if(_num_coords.isNotNull())
2786 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2787 if(_name_coords.isNotNull())
2788 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2789 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2791 if((*it).isNotNull())
2792 (*it)->clearNonDiscrAttributes();
2796 void MEDFileUMesh::setName(const std::string& name)
2798 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2799 if((*it).isNotNull())
2800 (*it)->setName(name);
2801 MEDFileMesh::setName(name);
2804 MEDFileUMesh::MEDFileUMesh()
2808 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2811 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2813 catch(INTERP_KERNEL::Exception& e)
2819 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2820 * See MEDFileUMesh::LoadPartOf for detailed description.
2824 void MEDFileUMesh::loadPartUMeshFromFile(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)
2826 MEDFileUMeshL2 loaderl2;
2827 MEDCoupling::MEDCouplingMeshType meshType;
2830 MEDCoupling::MEDCouplingAxisType dummy3;
2831 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2832 if(meshType!=UNSTRUCTURED)
2834 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2835 throw INTERP_KERNEL::Exception(oss.str().c_str());
2837 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2838 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2842 * \brief Write joints in a file
2844 void MEDFileMesh::writeJoints(med_idt fid) const
2846 if ( _joints.isNotNull() )
2847 _joints->writeLL(fid);
2851 * \brief Load joints in a file or use provided ones
2853 //================================================================================
2855 * \brief Load joints in a file or use provided ones
2856 * \param [in] fid - MED file descriptor
2857 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2858 * Usually this joints are those just read by another iteration
2859 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2861 //================================================================================
2863 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2865 if ( toUseInstedOfReading )
2866 setJoints( toUseInstedOfReading );
2868 _joints = MEDFileJoints::New( fid, _name );
2871 void MEDFileMesh::loadEquivalences(med_idt fid)
2873 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2875 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2878 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2880 const MEDFileEquivalences *equiv(other._equiv);
2882 _equiv=equiv->deepCopy(this);
2885 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2887 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2888 if(!thisEq && !otherEq)
2890 if(thisEq && otherEq)
2891 return thisEq->isEqual(otherEq,what);
2894 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2899 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2901 const MEDFileEquivalences *equiv(_equiv);
2904 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2905 _equiv->getRepr(oss);
2908 void MEDFileMesh::checkCartesian() const
2910 if(getAxisType()!=AX_CART)
2912 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()) << ").";
2913 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2914 oss << " - call setAxisType(AX_CART)" << std::endl;
2915 oss << " - call cartesianize()";
2916 throw INTERP_KERNEL::Exception(oss.str().c_str());
2921 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2923 int MEDFileMesh::getNumberOfJoints() const
2925 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2929 * \brief Return joints with all adjacent mesh domains
2931 MEDFileJoints * MEDFileMesh::getJoints() const
2933 return const_cast<MEDFileJoints*>(& (*_joints));
2936 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2938 if ( joints != _joints )
2947 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2949 * \sa loadPartUMeshFromFile
2951 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2953 MEDFileUMeshL2 loaderl2;
2954 MEDCoupling::MEDCouplingMeshType meshType;
2957 MEDCoupling::MEDCouplingAxisType axType;
2958 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2959 setAxisType(axType);
2960 if(meshType!=UNSTRUCTURED)
2962 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2963 throw INTERP_KERNEL::Exception(oss.str().c_str());
2965 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2966 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2967 // Structure element part...
2968 med_int nModels(-1);
2970 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2971 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2975 _elt_str.resize(nModels);
2976 for(int i=0;i<nModels;i++)
2977 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2980 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2982 int lev=loaderl2.getNumberOfLevels();
2984 for(int i=0;i<lev;i++)
2986 if(!loaderl2.emptyLev(i))
2987 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2991 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2993 setName(loaderl2.getName());
2994 setDescription(loaderl2.getDescription());
2995 setUnivName(loaderl2.getUnivName());
2996 setIteration(loaderl2.getIteration());
2997 setOrder(loaderl2.getOrder());
2998 setTimeValue(loaderl2.getTime());
2999 setTimeUnit(loaderl2.getTimeUnit());
3000 _coords=loaderl2.getCoords();
3001 if(!mrs || mrs->isNodeFamilyFieldReading())
3002 _fam_coords=loaderl2.getCoordsFamily();
3003 if(!mrs || mrs->isNodeNumFieldReading())
3004 _num_coords=loaderl2.getCoordsNum();
3005 if(!mrs || mrs->isNodeNameFieldReading())
3006 _name_coords=loaderl2.getCoordsName();
3007 if(!mrs || mrs->isGlobalNodeNumFieldReading())
3008 _global_num_coords=loaderl2.getCoordsGlobalNum();
3009 _part_coords=loaderl2.getPartDefOfCoo();
3013 MEDFileUMesh::~MEDFileUMesh()
3017 void MEDFileUMesh::writeMeshLL(med_idt fid) const
3019 const DataArrayDouble *coo=_coords;
3020 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3021 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3022 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3023 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3024 int spaceDim=(int)(coo?coo->getNumberOfComponents():0);
3027 mdim=getMeshDimension();
3028 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3029 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3030 for(int i=0;i<spaceDim;i++)
3032 std::string info=coo->getInfoOnComponent(i);
3034 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3035 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
3036 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
3038 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
3040 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
3041 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
3042 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
3043 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3044 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3045 (*it)->write(fid,meshName,mdim);
3046 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
3050 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
3051 * \return std::vector<int> - a sequence of the relative dimensions.
3053 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
3055 std::vector<int> ret;
3057 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3058 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3065 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
3066 * \return std::vector<int> - a sequence of the relative dimensions.
3068 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
3070 std::vector<int> ret0=getNonEmptyLevels();
3071 if((const DataArrayDouble *) _coords)
3073 std::vector<int> ret(ret0.size()+1);
3075 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3081 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
3083 std::vector<int> ret;
3084 const DataArrayIdType *famCoo(_fam_coords);
3088 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3090 const MEDFileUMeshSplitL1 *cur(*it);
3092 if(cur->getFamilyField())
3098 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3100 std::vector<int> ret;
3101 if(_num_coords.isNotNull())
3104 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3106 const MEDFileUMeshSplitL1 *cur(*it);
3108 if(cur->getNumberField())
3114 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3116 std::vector<int> ret;
3117 const DataArrayAsciiChar *nameCoo(_name_coords);
3121 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3123 const MEDFileUMeshSplitL1 *cur(*it);
3125 if(cur->getNameField())
3132 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3133 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3134 * \param [in] fams - the name of the family of interest.
3135 * \return std::vector<int> - a sequence of the relative dimensions.
3137 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3139 std::vector<mcIdType> ret;
3140 std::vector<int> levs(getNonEmptyLevels());
3141 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3142 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3143 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3149 * Returns all relative mesh levels (including nodes) where given families are defined.
3150 * \param [in] fams - the names of the families of interest.
3151 * \return std::vector<int> - a sequence of the relative dimensions.
3153 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3155 std::vector<mcIdType> ret0(getFamsNonEmptyLevels(fams));
3156 const DataArrayIdType *famCoords(_fam_coords);
3159 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3160 if(famCoords->presenceOfValue(famIds))
3162 std::vector<mcIdType> ret(ret0.size()+1);
3164 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3171 mcIdType MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3173 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3174 if((const DataArrayIdType *)_fam_coords)
3176 mcIdType val=_fam_coords->getMaxValue(tmp);
3177 ret=std::max(ret,std::abs(val));
3179 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3181 if((const MEDFileUMeshSplitL1 *)(*it))
3183 const DataArrayIdType *da=(*it)->getFamilyField();
3186 mcIdType val=da->getMaxValue(tmp);
3187 ret=std::max(ret,std::abs(val));
3194 mcIdType MEDFileUMesh::getMaxFamilyIdInArrays() const
3196 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3197 if((const DataArrayIdType *)_fam_coords)
3199 mcIdType val=_fam_coords->getMaxValue(tmp);
3200 ret=std::max(ret,val);
3202 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3204 if((const MEDFileUMeshSplitL1 *)(*it))
3206 const DataArrayIdType *da=(*it)->getFamilyField();
3209 mcIdType val=da->getMaxValue(tmp);
3210 ret=std::max(ret,val);
3217 mcIdType MEDFileUMesh::getMinFamilyIdInArrays() const
3219 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
3220 if((const DataArrayIdType *)_fam_coords)
3222 mcIdType val=_fam_coords->getMinValue(tmp);
3223 ret=std::min(ret,val);
3225 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3227 if((const MEDFileUMeshSplitL1 *)(*it))
3229 const DataArrayIdType *da=(*it)->getFamilyField();
3232 mcIdType val=da->getMinValue(tmp);
3233 ret=std::min(ret,val);
3241 * Returns the dimension on cells in \a this mesh.
3242 * \return int - the mesh dimension.
3243 * \throw If there are no cells in this mesh.
3245 int MEDFileUMesh::getMeshDimension() const
3248 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3249 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3250 return (*it)->getMeshDimension()+lev;
3251 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3255 * Returns the space dimension of \a this mesh that is equal to number of components in
3256 * the node coordinates array.
3257 * \return int - the space dimension of \a this mesh.
3258 * \throw If the node coordinates array is not available.
3260 int MEDFileUMesh::getSpaceDimension() const
3262 const DataArrayDouble *coo=_coords;
3264 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3265 return (int)coo->getNumberOfComponents();
3269 * Returns a string describing \a this mesh.
3270 * \return std::string - the mesh information string.
3272 std::string MEDFileUMesh::simpleRepr() const
3274 std::ostringstream oss;
3275 oss << MEDFileMesh::simpleRepr();
3276 const DataArrayDouble *coo=_coords;
3277 oss << "- The dimension of the space is ";
3278 static const char MSG1[]= "*** NO COORDS SET ***";
3279 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3281 oss << _coords->getNumberOfComponents() << std::endl;
3283 oss << MSG1 << std::endl;
3284 oss << "- Type of the mesh : UNSTRUCTURED\n";
3285 oss << "- Number of nodes : ";
3287 oss << _coords->getNumberOfTuples() << std::endl;
3289 oss << MSG1 << std::endl;
3290 std::size_t nbOfLev=_ms.size();
3291 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3292 for(std::size_t i=0;i<nbOfLev;i++)
3294 const MEDFileUMeshSplitL1 *lev=_ms[i];
3295 oss << " - Level #" << -((int) i) << " has dimension : ";
3298 oss << lev->getMeshDimension() << std::endl;
3299 lev->simpleRepr(oss);
3302 oss << MSG2 << std::endl;
3304 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3307 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3308 oss << "- Names of coordinates :" << std::endl;
3309 std::vector<std::string> vars=coo->getVarsOnComponent();
3310 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3311 oss << std::endl << "- Units of coordinates : " << std::endl;
3312 std::vector<std::string> units=coo->getUnitsOnComponent();
3313 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3315 oss << std::endl << std::endl;
3317 getEquivalencesRepr(oss);
3322 * Returns a full textual description of \a this mesh.
3323 * \return std::string - the string holding the mesh description.
3325 std::string MEDFileUMesh::advancedRepr() const
3327 return simpleRepr();
3331 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3332 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3333 * \return mcIdType - the number of entities.
3334 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3336 mcIdType MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3338 if(meshDimRelToMaxExt==1)
3340 if(!((const DataArrayDouble *)_coords))
3341 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3342 return _coords->getNumberOfTuples();
3344 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3348 * Returns the family field for mesh entities of a given dimension.
3349 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3350 * \return const DataArrayIdType * - the family field. It is an array of ids of families
3351 * each mesh entity belongs to. It can be \c NULL.
3353 const DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3355 if(meshDimRelToMaxExt==1)
3357 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3358 return l1->getFamilyField();
3361 DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3363 if(meshDimRelToMaxExt==1)
3365 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3366 return l1->getFamilyField();
3370 * Returns the optional numbers of mesh entities of a given dimension.
3371 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3372 * \return const DataArrayIdType * - the array of the entity numbers.
3373 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3375 const DataArrayIdType *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3377 if(meshDimRelToMaxExt==1)
3379 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3380 return l1->getNumberField();
3383 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3385 if(meshDimRelToMaxExt==1)
3386 return _name_coords;
3387 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3388 return l1->getNameField();
3391 MCAuto<DataArrayIdType> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3393 if(meshDimRelToMaxExt!=1)
3394 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3395 return _global_num_coords;
3399 * 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).
3401 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3402 * \param [in] gt - The input geometric type for which the part definition is requested.
3403 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3405 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3407 if(meshDimRelToMaxExt==1)
3408 return _part_coords;
3409 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3410 return l1->getPartDef(gt);
3413 mcIdType MEDFileUMesh::getNumberOfNodes() const
3415 const DataArrayDouble *coo(_coords);
3417 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3418 return coo->getNumberOfTuples();
3421 mcIdType MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3423 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3424 return l1->getNumberOfCells();
3427 bool MEDFileUMesh::hasImplicitPart() const
3432 mcIdType MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3434 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3437 void MEDFileUMesh::releaseImplicitPartIfAny() const
3441 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3443 std::size_t sz(st.getNumberOfItems());
3444 for(std::size_t i=0;i<sz;i++)
3446 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3447 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3448 if(st[i].getPflName().empty())
3449 m->computeNodeIdsAlg(nodesFetched);
3452 const DataArrayIdType *arr(globs->getProfile(st[i].getPflName()));
3453 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3454 m2->computeNodeIdsAlg(nodesFetched);
3459 MEDFileMesh *MEDFileUMesh::cartesianize() const
3461 if(getAxisType()==AX_CART)
3464 return const_cast<MEDFileUMesh *>(this);
3468 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3469 const DataArrayDouble *coords(_coords);
3471 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3472 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3473 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3474 if((const MEDFileUMeshSplitL1 *)(*it))
3475 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3476 ret->_coords=coordsCart;
3477 ret->setAxisType(AX_CART);
3482 bool MEDFileUMesh::presenceOfStructureElements() const
3484 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3485 if((*it).isNotNull())
3490 void MEDFileUMesh::killStructureElements()
3496 * Returns the optional numbers of mesh entities of a given dimension transformed using
3497 * DataArrayIdType::invertArrayN2O2O2N().
3498 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3499 * \return const DataArrayIdType * - the array of the entity numbers transformed using
3500 * DataArrayIdType::invertArrayN2O2O2N().
3501 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3503 const DataArrayIdType *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3505 if(meshDimRelToMaxExt==1)
3507 if(_num_coords.isNull())
3508 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3509 return _rev_num_coords;
3511 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3512 return l1->getRevNumberField();
3516 * Returns a pointer to the node coordinates array of \a this mesh \b without
3517 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3519 DataArrayDouble *MEDFileUMesh::getCoords() const
3522 MCAuto<DataArrayDouble> tmp(_coords);
3523 if((DataArrayDouble *)tmp)
3531 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3532 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3534 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3535 * \param [in] grp - the name of the group whose mesh entities are included in the
3537 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3538 * according to the optional numbers of entities, if available.
3539 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3540 * delete this mesh using decrRef() as it is no more needed.
3541 * \throw If the name of a nonexistent group is specified.
3542 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3544 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3547 synchronizeTinyInfoOnLeaves();
3548 std::vector<std::string> tmp(1);
3550 return getGroups(meshDimRelToMaxExt,tmp,renum);
3554 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3555 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3557 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3558 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3560 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3561 * according to the optional numbers of entities, if available.
3562 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3563 * delete this mesh using decrRef() as it is no more needed.
3564 * \throw If a name of a nonexistent group is present in \a grps.
3565 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3567 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3570 synchronizeTinyInfoOnLeaves();
3571 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3572 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3573 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3574 zeRet->setName(grps[0]);
3575 return zeRet.retn();
3579 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3580 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3582 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3583 * \param [in] fam - the name of the family whose mesh entities are included in the
3585 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3586 * according to the optional numbers of entities, if available.
3587 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3588 * delete this mesh using decrRef() as it is no more needed.
3589 * \throw If a name of a nonexistent family is present in \a grps.
3590 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3592 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3595 synchronizeTinyInfoOnLeaves();
3596 std::vector<std::string> tmp(1);
3598 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3602 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3603 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3605 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3606 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3608 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3609 * according to the optional numbers of entities, if available.
3610 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3611 * delete this mesh using decrRef() as it is no more needed.
3612 * \throw If a name of a nonexistent family is present in \a fams.
3613 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3615 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3618 synchronizeTinyInfoOnLeaves();
3619 if(meshDimRelToMaxExt==1)
3621 MCAuto<DataArrayIdType> arr=getFamiliesArr(1,fams,renum);
3622 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3623 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3627 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3628 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3629 MCAuto<MEDCouplingUMesh> zeRet;
3631 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3633 zeRet=l1->getFamilyPart(0,0,renum);
3634 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3635 zeRet->setName(fams[0]);
3636 return zeRet.retn();
3640 * Returns ids of mesh entities contained in given families of a given dimension.
3641 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3643 * \param [in] fams - the names of the families of interest.
3644 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3645 * returned instead of ids.
3646 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
3647 * numbers, if available and required, of mesh entities of the families. The caller
3648 * is to delete this array using decrRef() as it is no more needed.
3649 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3651 DataArrayIdType *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3653 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3654 if(meshDimRelToMaxExt==1)
3656 if((const DataArrayIdType *)_fam_coords)
3658 MCAuto<DataArrayIdType> da;
3660 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3662 da=_fam_coords->findIdsEqualList(0,0);
3664 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3669 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3671 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3673 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3675 return l1->getFamilyPartArr(0,0,renum);
3679 * Returns a MEDCouplingUMesh of a given relative dimension.
3680 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3681 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3682 * To build a valid MEDCouplingUMesh from the returned one in this case,
3683 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3684 * \param [in] meshDimRelToMax - the relative dimension of interest.
3685 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3686 * optional numbers of mesh entities.
3687 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3688 * delete using decrRef() as it is no more needed.
3689 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3691 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3694 synchronizeTinyInfoOnLeaves();
3695 if(meshDimRelToMaxExt==1)
3699 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3700 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3701 umesh->setCoords(cc);
3702 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3703 umesh->setName(getName());
3707 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3708 return l1->getWholeMesh(renum);
3711 std::vector<mcIdType> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3713 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3714 return l1->getDistributionOfTypes();
3718 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3719 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3720 * optional numbers of mesh entities.
3721 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3722 * delete using decrRef() as it is no more needed.
3723 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3725 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3727 return getMeshAtLevel(0,renum);
3731 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3732 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3733 * optional numbers of mesh entities.
3734 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3735 * delete using decrRef() as it is no more needed.
3736 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3738 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3740 return getMeshAtLevel(-1,renum);
3744 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3745 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3746 * optional numbers of mesh entities.
3747 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3748 * delete using decrRef() as it is no more needed.
3749 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3751 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3753 return getMeshAtLevel(-2,renum);
3757 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3758 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3759 * optional numbers of mesh entities.
3760 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3761 * delete using decrRef() as it is no more needed.
3762 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3764 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3766 return getMeshAtLevel(-3,renum);
3770 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3771 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3772 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3773 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3775 void MEDFileUMesh::forceComputationOfParts() const
3777 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3779 const MEDFileUMeshSplitL1 *elt(*it);
3781 elt->forceComputationOfParts();
3786 * This method returns a vector of mesh parts containing each exactly one geometric type.
3787 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3788 * This method is only for memory aware users.
3789 * The returned pointers are **NOT** new object pointer. No need to mange them.
3791 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3794 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3795 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3799 * This method returns the part of \a this having the geometric type \a gt.
3800 * If such part is not existing an exception will be thrown.
3801 * The returned pointer is **NOT** new object pointer. No need to mange it.
3803 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3806 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3807 int lev=(int)cm.getDimension()-getMeshDimension();
3808 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3809 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3813 * This method returns for each geo types in \a this number of cells with this geo type.
3814 * 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.
3815 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3817 * \sa getDistributionOfTypes
3819 std::vector< std::pair<int,mcIdType> > MEDFileUMesh::getAllDistributionOfTypes() const
3821 std::vector< std::pair<int,mcIdType> > ret;
3822 std::vector<int> nel(getNonEmptyLevels());
3823 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3825 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3826 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3828 mcIdType nbCells(getNumberOfCellsWithType(*it1));
3829 ret.push_back(std::pair<int,mcIdType>(*it1,nbCells));
3832 ret.push_back(std::pair<int,mcIdType>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3837 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3838 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3840 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3842 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3843 return sp->getGeoTypes();
3846 mcIdType MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3848 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3849 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3850 return sp->getNumberOfCellsWithType(ct);
3854 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3855 * \param [in] gt - the geometric type for which the family field is asked.
3856 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
3857 * delete using decrRef() as it is no more needed.
3858 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3860 DataArrayIdType *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3862 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3863 int lev=(int)cm.getDimension()-getMeshDimension();
3864 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3865 return sp->extractFamilyFieldOnGeoType(gt);
3869 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3870 * \param [in] gt - the geometric type for which the number field is asked.
3871 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
3872 * delete using decrRef() as it is no more needed.
3873 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3875 DataArrayIdType *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3877 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3878 int lev=(int)cm.getDimension()-getMeshDimension();
3879 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3880 return sp->extractNumberFieldOnGeoType(gt);
3884 * This method returns for specified geometric type \a gt the relative level to \a this.
3885 * If the relative level is empty an exception will be thrown.
3887 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3889 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3890 int ret((int)cm.getDimension()-getMeshDimension());
3891 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3895 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3897 if(meshDimRelToMaxExt==1)
3898 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3899 if(meshDimRelToMaxExt>1)
3900 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3901 int tracucedRk=-meshDimRelToMaxExt;
3902 if(tracucedRk>=(int)_ms.size())
3903 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3904 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3905 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3906 return _ms[tracucedRk];
3909 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3911 if(meshDimRelToMaxExt==1)
3912 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3913 if(meshDimRelToMaxExt>1)
3914 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3915 int tracucedRk=-meshDimRelToMaxExt;
3916 if(tracucedRk>=(int)_ms.size())
3917 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3918 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3919 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3920 return _ms[tracucedRk];
3923 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3925 if(-meshDimRelToMax>=(int)_ms.size())
3926 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3928 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3930 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3932 int ref=(*it)->getMeshDimension();
3933 if(ref+i!=meshDim-meshDimRelToMax)
3934 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3940 * Sets the node coordinates array of \a this mesh.
3941 * \param [in] coords - the new node coordinates array.
3942 * \throw If \a coords == \c NULL.
3944 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3947 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3948 if(coords==(DataArrayDouble *)_coords)
3950 coords->checkAllocated();
3951 mcIdType nbOfTuples(coords->getNumberOfTuples());
3952 _coords.takeRef(coords);
3953 _fam_coords=DataArrayIdType::New();
3954 _fam_coords->alloc(nbOfTuples,1);
3955 _fam_coords->fillWithZero();
3956 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3957 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3958 if((MEDFileUMeshSplitL1 *)(*it))
3959 (*it)->setCoords(coords);
3963 * Change coords without changing anything concerning families and numbering on nodes.
3965 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3968 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3969 if(coords==(DataArrayDouble *)_coords)
3971 coords->checkAllocated();
3972 mcIdType nbOfTuples(coords->getNumberOfTuples());
3973 if(_coords.isNull())
3980 mcIdType oldNbTuples(_coords->getNumberOfTuples());
3981 if(oldNbTuples!=nbOfTuples)
3982 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3986 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3987 if((MEDFileUMeshSplitL1 *)(*it))
3988 (*it)->setCoords(coords);
3992 * Removes all groups of a given dimension in \a this mesh.
3993 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3994 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3996 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3998 if(meshDimRelToMaxExt==1)
4000 if((DataArrayIdType *)_fam_coords)
4001 _fam_coords->fillWithZero();
4004 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
4005 l1->eraseFamilyField();
4010 * Removes all families with ids not present in the family fields of \a this mesh.
4012 void MEDFileUMesh::optimizeFamilies()
4014 std::vector<int> levs=getNonEmptyLevelsExt();
4015 std::set<mcIdType> allFamsIds;
4016 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4018 const DataArrayIdType *ffield=getFamilyFieldAtLevel(*it);
4019 MCAuto<DataArrayIdType> ids=ffield->getDifferentValues();
4020 std::set<mcIdType> res;
4021 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
4024 std::set<std::string> famNamesToKill;
4025 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
4027 if(allFamsIds.find((*it).second)!=allFamsIds.end())
4028 famNamesToKill.insert((*it).first);
4030 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
4031 _families.erase(*it);
4032 std::vector<std::string> grpNamesToKill;
4033 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
4035 std::vector<std::string> tmp;
4036 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
4038 if(famNamesToKill.find(*it2)==famNamesToKill.end())
4039 tmp.push_back(*it2);
4044 tmp.push_back((*it).first);
4046 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
4051 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
4052 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
4053 * The boundary is built according to the following method:
4054 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
4055 * coordinates array is extended).
4056 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
4057 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
4058 * might not be duplicated at all.
4059 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
4060 * other side of the group is no more a neighbor)
4061 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
4062 * bordering the newly created boundary use the newly computed nodes.
4063 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
4064 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
4066 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
4067 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
4069 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
4070 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
4071 * \sa clearNodeAndCellNumbers()
4073 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayIdType *&nodesDuplicated,
4074 DataArrayIdType *&cellsModified, DataArrayIdType *&cellsNotModified)
4076 typedef MCAuto<MEDCouplingUMesh> MUMesh;
4077 typedef MCAuto<DataArrayIdType> DAInt;
4079 std::vector<int> levs=getNonEmptyLevels();
4080 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
4081 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
4082 MUMesh m0=getMeshAtLevel(0);
4083 MUMesh m1=getMeshAtLevel(-1);
4084 mcIdType nbNodes=m0->getNumberOfNodes();
4085 MUMesh m11=getGroup(-1,grpNameM1);
4086 DataArrayIdType *tmp00=0,*tmp11=0,*tmp22=0;
4087 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
4088 DAInt nodeIdsToDuplicate(tmp00);
4089 DAInt cellsToModifyConn0(tmp11);
4090 DAInt cellsToModifyConn1(tmp22);
4091 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4092 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4093 DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New();
4094 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4095 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4096 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4097 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4098 DataArrayIdType *cellsInM1ToRenumW4Tmp=0;
4099 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4100 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4101 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4102 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4103 DAInt grpIds=getGroupArr(-1,grpNameM1);
4104 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4105 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4106 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4107 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4108 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4109 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4110 m0->setCoords(tmp0->getCoords());
4111 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4112 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4113 m1->setCoords(m0->getCoords());
4114 _coords=m0->getCoords(); _coords->incrRef();
4115 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4116 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4117 DataArrayIdType * duplCells;
4118 m1->areCellsIncludedIn(m11, 0, duplCells);
4119 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4120 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4121 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4122 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4123 DAInt szOfCellGrpOfSameType(tmp00);
4124 DAInt idInMsOfCellGrpOfSameType(tmp11);
4126 newm1->setName(getName());
4127 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
4129 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4130 DAInt newFam=DataArrayIdType::New();
4131 newFam->alloc(newm1->getNumberOfCells(),1);
4132 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4133 // Positive ID for family of nodes, negative for all the rest.
4135 if (m1->getMeshDimension() == 0)
4136 idd=getMaxFamilyId()+1;
4138 idd=getMinFamilyId()-1;
4139 mcIdType globStart=0,start=0,end,globEnd;
4140 mcIdType nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4141 for(mcIdType i=0;i<nbOfChunks;i++)
4143 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4144 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4146 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4147 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4148 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4153 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4157 newm1->setCoords(getCoords());
4158 setMeshAtLevel(-1,newm1);
4159 setFamilyFieldArr(-1,newFam);
4160 std::string grpName2(grpNameM1); grpName2+="_dup";
4161 addFamily(grpName2,idd);
4162 addFamilyOnGrp(grpName2,grpName2);
4167 mcIdType newNbOfNodes=getCoords()->getNumberOfTuples();
4168 newFam=DataArrayIdType::New(); newFam->alloc(newNbOfNodes,1);
4169 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4170 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4174 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4176 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4177 it != _ms.end(); it++)
4180 (*it)->_rev_num = 0;
4182 nodesDuplicated=nodeIdsToDuplicate.retn();
4183 cellsModified=cellsToModifyConn0.retn();
4184 cellsNotModified=cellsToModifyConn1.retn();
4187 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4188 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4191 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4192 * \param [out] newCode retrieves the distribution of types after the call if true is returned
4193 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4195 * \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.
4196 * 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.
4198 bool MEDFileUMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
4200 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4201 std::vector<int> levs=getNonEmptyLevels();
4203 std::vector< const DataArrayIdType* > renumCellsSplited;//same than memorySaverIfThrow
4204 std::vector< MCAuto<DataArrayIdType> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4207 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4209 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4210 std::vector<mcIdType> code1=m->getDistributionOfTypes();
4211 end=PutInThirdComponentOfCodeOffset(code1,start);
4212 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4213 bool hasChanged=m->unPolyze();
4214 DataArrayIdType *fake=0;
4215 MCAuto<DataArrayIdType> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4216 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4218 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4221 MCAuto<DataArrayIdType> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4222 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4224 MCAuto<DataArrayIdType> famField2,numField2;
4225 const DataArrayIdType *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayIdType *>(famField); }
4226 const DataArrayIdType *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayIdType *>(numField); }
4227 setMeshAtLevel(*it,m);
4228 std::vector<mcIdType> code2=m->getDistributionOfTypes();
4229 end=PutInThirdComponentOfCodeOffset(code2,start);
4230 newCode.insert(newCode.end(),code2.begin(),code2.end());
4232 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4236 MCAuto<DataArrayIdType> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4237 setFamilyFieldArr(*it,newFamField);
4241 MCAuto<DataArrayIdType> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4242 setRenumFieldArr(*it,newNumField);
4247 newCode.insert(newCode.end(),code1.begin(),code1.end());
4253 MCAuto<DataArrayIdType> renumCells=DataArrayIdType::Aggregate(renumCellsSplited);
4254 MCAuto<DataArrayIdType> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4255 o2nRenumCell=o2nRenumCellRet.retn();
4260 /*! \cond HIDDEN_ITEMS */
4261 struct MEDLoaderAccVisit1
4263 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4264 mcIdType operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4265 mcIdType _new_nb_of_nodes;
4270 * 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.
4271 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4272 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4273 * -1 values in returned array means that the corresponding old node is no more used.
4275 * \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
4276 * is modified in \a this.
4277 * \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
4280 DataArrayIdType *MEDFileUMesh::zipCoords()
4282 const DataArrayDouble *coo(getCoords());
4284 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4285 mcIdType nbOfNodes(coo->getNumberOfTuples());
4286 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4287 std::vector<int> neLevs(getNonEmptyLevels());
4288 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4290 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4291 if(zeLev->isMeshStoredSplitByType())
4293 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4294 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4296 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4300 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4301 mesh->computeNodeIdsAlg(nodeIdsInUse);
4304 mcIdType nbrOfNodesInUse((mcIdType)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4305 if(nbrOfNodesInUse==nbOfNodes)
4306 return 0;//no need to update _part_coords
4307 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfNodes,1);
4308 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4309 MCAuto<DataArrayIdType> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4310 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4311 MCAuto<DataArrayIdType> newFamCoords;
4312 MCAuto<DataArrayAsciiChar> newNameCoords;
4313 if((const DataArrayIdType *)_fam_coords)
4314 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4315 MCAuto<DataArrayIdType> newNumCoords,newGlobalNumCoords;
4316 if(_num_coords.isNotNull())
4317 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4318 if(_global_num_coords.isNotNull())
4319 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4320 if(_name_coords.isNotNull())
4321 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4322 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4323 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4325 if((MEDFileUMeshSplitL1*)*it)
4327 (*it)->renumberNodesInConn(ret->begin());
4328 (*it)->setCoords(_coords);
4331 // updates _part_coords
4332 const PartDefinition *pc(_part_coords);
4335 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4336 _part_coords=tmpPD->composeWith(pc);
4342 * This method is the extension of MEDCouplingUMesh::computeFetchedNodeIds. Except that here all levels are considered here.
4344 * \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.
4346 DataArrayIdType *MEDFileUMesh::computeFetchedNodeIds() const
4348 std::vector<int> neLevs(this->getNonEmptyLevels());
4349 std::vector<bool> nodesHighlighted(this->getNumberOfNodes(),false);
4350 for(auto lev : neLevs)
4352 const MEDFileUMeshSplitL1 *zeLev(this->getMeshAtLevSafe(lev));
4353 zeLev->highlightUsedNodes(nodesHighlighted);
4355 return DataArrayIdType::BuildListOfSwitchedOn(nodesHighlighted);
4359 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4360 * The extraction of \a this is specified by the extractDef \a input map.
4361 * This map tells for each level of cells, the cells kept in the extraction.
4363 * \return - a new reference of DataArrayIdType that represents sorted node ids, the extraction is lying on.
4364 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4366 DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4368 std::vector<int> levs(getNonEmptyLevels());
4369 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4370 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4373 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4374 if((*it).second.isNull())
4375 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4378 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4380 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4381 throw INTERP_KERNEL::Exception(oss.str());
4383 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4384 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4385 mPart->computeNodeIdsAlg(fetchedNodes);
4387 return DataArrayIdType::BuildListOfSwitchedOn(fetchedNodes);
4391 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4393 * \return - a new reference of MEDFileUMesh
4394 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4396 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4398 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4399 std::vector<int> levs(getNonEmptyLevels());
4400 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4403 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4404 if((*it).second.isNull())
4405 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4408 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4410 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4411 throw INTERP_KERNEL::Exception(oss.str());
4413 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4414 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4415 ret->setMeshAtLevel((*it).first,mPart);
4416 const DataArrayIdType *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4419 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4420 ret->setFamilyFieldArr((*it).first,famPart);
4424 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4425 ret->setFamilyFieldArr((*it).first,numPart);
4428 std::map<int, MCAuto<DataArrayIdType> >::const_iterator it2(extractDef.find(1));
4429 if(it2!=extractDef.end())
4431 const DataArrayDouble *coo(ret->getCoords());
4433 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4434 MCAuto<DataArrayIdType> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4435 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4436 ret->setCoords(cooPart);
4437 const DataArrayIdType *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4440 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4441 ret->setFamilyFieldArr(1,famPart);
4445 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4446 ret->setFamilyFieldArr(1,numPart);
4448 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4452 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4453 m->renumberNodesInConn(o2nNodes->begin());
4454 ret->setMeshAtLevel((*it3).first,m);
4461 * This method performs an extrusion along a path defined by \a m1D.
4462 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4463 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4464 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4465 * This method scans all levels in \a this
4466 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4468 * \param [in] m1D - the mesh defining the extrusion path.
4469 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4470 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4472 * \sa MEDCouplingUMesh::buildExtrudedMesh
4474 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4477 if(getMeshDimension()!=2)
4478 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4479 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4480 m1D->checkConsistencyLight();
4481 if(m1D->getMeshDimension()!=1)
4482 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4483 mcIdType nbRep(m1D->getNumberOfCells());
4484 std::vector<int> levs(getNonEmptyLevels());
4485 std::vector<std::string> grps(getGroupsNames());
4486 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4487 DataArrayDouble *coords(0);
4488 std::size_t nbOfLevsOut(levs.size()+1);
4489 std::vector< MCAuto<DataArrayIdType> > o2ns(nbOfLevsOut);
4490 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4492 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4493 item=item->clone(false);
4494 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4495 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4496 tmp->changeSpaceDimension(3+(*lev),0.);
4497 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4498 zeList.push_back(elt);
4500 coords=elt->getCoords();
4503 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4504 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4506 (*it)->setName(getName());
4507 (*it)->setCoords(coords);
4509 for(std::size_t ii=0;ii!=zeList.size();ii++)
4512 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4515 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4516 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4517 MCAuto<DataArrayIdType> tmp(elt2->getNodalConnectivity()->deepCopy());
4518 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4519 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4520 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4521 std::vector<const MEDCouplingUMesh *> elts(3);
4522 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4523 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4524 elt->setName(getName());
4527 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4528 ret->setMeshAtLevel(lev,elt);
4530 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4531 endLev=endLev->clone(false); endLev->setCoords(coords);
4532 MCAuto<DataArrayIdType> tmp(endLev->getNodalConnectivity()->deepCopy());
4533 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4534 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4535 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4536 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4537 endLev->setName(getName());
4538 ret->setMeshAtLevel(levs.back()-1,endLev);
4540 for(std::size_t ii=0;ii!=zeList.size();ii++)
4543 std::vector< MCAuto<DataArrayIdType> > outGrps;
4544 std::vector< const DataArrayIdType * > outGrps2;
4547 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4549 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev+1,*grp));
4550 if(!grpArr->empty())
4552 MCAuto<DataArrayIdType> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4553 mcIdType offset0(zeList[ii]->getNumberOfCells());
4554 mcIdType offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4555 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4556 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4557 grpArr2->setName(oss.str());
4558 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4559 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4560 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4561 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4566 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4568 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev,*grp));
4569 if(!grpArr->empty())
4571 mcIdType nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4572 std::vector< MCAuto<DataArrayIdType> > grpArrs(nbRep);
4573 std::vector< const DataArrayIdType *> grpArrs2(nbRep);
4574 for(int iii=0;iii<nbRep;iii++)
4576 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4577 grpArrs2[iii]=grpArrs[iii];
4579 MCAuto<DataArrayIdType> grpArrExt(DataArrayIdType::Aggregate(grpArrs2));
4580 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4581 std::ostringstream grpName; grpName << *grp << "_extruded";
4582 grpArrExt->setName(grpName.str());
4583 outGrps.push_back(grpArrExt);
4584 outGrps2.push_back(grpArrExt);
4587 ret->setGroupsAtLevel(lev,outGrps2);
4589 std::vector< MCAuto<DataArrayIdType> > outGrps;
4590 std::vector< const DataArrayIdType * > outGrps2;
4591 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4593 MCAuto<DataArrayIdType> grpArr1(getGroupArr(levs.back(),*grp));
4594 if(grpArr1->empty())
4596 MCAuto<DataArrayIdType> grpArr2(grpArr1->deepCopy());
4597 std::ostringstream grpName; grpName << *grp << "_top";
4598 grpArr2->setName(grpName.str());
4599 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4600 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4601 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4603 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4608 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4609 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4610 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4612 * \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
4613 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4614 * \param [in] eps - detection threshold for coordinates.
4615 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4617 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4619 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4622 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4623 mcIdType initialNbNodes(getNumberOfNodes());
4624 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4625 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4627 MCAuto<DataArrayIdType> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4629 DataArrayDouble *zeCoords(m0->getCoords());
4630 ret->setMeshAtLevel(0,m0);
4631 std::vector<int> levs(getNonEmptyLevels());
4632 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4635 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4636 ret->setFamilyFieldArr(0,famFieldCpy);
4638 famField=getFamilyFieldAtLevel(1);
4641 MCAuto<DataArrayIdType> fam(DataArrayIdType::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4642 fam->fillWithZero();
4643 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4644 ret->setFamilyFieldArr(1,fam);
4646 ret->copyFamGrpMapsFrom(*this);
4647 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4648 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4652 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4653 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4654 if(m1->getMeshDimension()!=0)
4657 MCAuto<DataArrayIdType> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4658 }//kill unused notUsed var
4659 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4660 DataArrayIdType *b(0);
4661 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4662 MCAuto<DataArrayIdType> bSafe(b);
4665 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4666 throw INTERP_KERNEL::Exception(oss.str().c_str());
4668 b->applyLin(1,initialNbNodes);
4669 MCAuto<DataArrayIdType> l0(DataArrayIdType::New()); l0->alloc(initialNbNodes,1); l0->iota();
4670 std::vector<const DataArrayIdType *> v(2); v[0]=l0; v[1]=b;
4671 MCAuto<DataArrayIdType> renum(DataArrayIdType::Aggregate(v));
4672 m1->renumberNodesInConn(renum->begin());
4674 m1->setCoords(zeCoords);
4675 ret->setMeshAtLevel(*lev,m1);
4676 famField=getFamilyFieldAtLevel(*lev);
4679 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4680 ret->setFamilyFieldArr(*lev,famFieldCpy);
4687 * This method converts all quadratic cells in \a this into linear cells.
4688 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4689 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4691 * \param [in] eps - detection threshold for coordinates.
4692 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4694 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4696 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4699 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4700 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4701 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4702 m0->convertQuadraticCellsToLinear();
4704 DataArrayDouble *zeCoords(m0->getCoords());
4705 ret->setMeshAtLevel(0,m0);
4706 std::vector<int> levs(getNonEmptyLevels());
4707 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4710 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4711 ret->setFamilyFieldArr(0,famFieldCpy);
4713 famField=getFamilyFieldAtLevel(1);
4716 MCAuto<DataArrayIdType> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4717 ret->setFamilyFieldArr(1,fam);
4719 ret->copyFamGrpMapsFrom(*this);
4720 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4724 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4725 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4726 m1->convertQuadraticCellsToLinear();
4728 DataArrayIdType *b(0);
4729 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4730 MCAuto<DataArrayIdType> bSafe(b);
4733 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4734 throw INTERP_KERNEL::Exception(oss.str().c_str());
4736 m1->renumberNodesInConn(b->begin());
4737 m1->setCoords(zeCoords);
4738 ret->setMeshAtLevel(*lev,m1);
4739 famField=getFamilyFieldAtLevel(*lev);
4742 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4743 ret->setFamilyFieldArr(*lev,famFieldCpy);
4750 * Computes the symmetry of \a this.
4751 * \return a new object.
4753 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4755 MCAuto<MEDFileUMesh> ret(deepCopy());
4756 DataArrayDouble *myCoo(getCoords());
4759 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4760 ret->setCoordsForced(newCoo);
4766 * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
4767 * merged in such a way that the final mesh contain all of them.
4768 * \return a new object.
4770 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4773 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4774 std::size_t sz(meshes.size()),i(0);
4775 std::vector<const DataArrayDouble *> coos(sz);
4776 std::vector<const DataArrayIdType *> fam_coos(sz),num_coos(sz);
4777 for(auto it=meshes.begin();it!=meshes.end();it++,i++)
4780 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4781 coos[i]=(*it)->getCoords();
4782 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4783 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4785 const MEDFileUMesh *ref(meshes[0]);
4786 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4787 std::vector<int> levs(ref->getNonEmptyLevels());
4788 std::map<int, std::vector<const DataArrayIdType *> > m_fam,m_renum;
4789 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4790 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4791 std::map<std::string,mcIdType> famNumMap;
4792 std::map<mcIdType, std::string> famNumMap_rev;
4793 std::map<std::string, std::vector<std::string> > grpFamMap;
4794 std::set< MCAuto<DataArrayIdType> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
4796 // Identify min family number used:
4797 mcIdType min_fam_num(0);
4798 for(const auto& msh : meshes)
4800 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4801 for(const auto& it3 : locMap1)
4802 if(it3.second < min_fam_num)
4803 min_fam_num = it3.second;
4806 for(const auto& msh : meshes)
4808 if(msh->getSpaceDimension()!=spaceDim)
4809 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4810 if(msh->getMeshDimension()!=meshDim)
4811 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4812 if(msh->getNonEmptyLevels()!=levs)
4813 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4815 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4816 std::map<std::string, std::string> substitute;
4817 std::map<mcIdType, mcIdType> substituteN;
4818 bool fam_conflict(false);
4819 for(const auto& it3 : locMap1)
4821 const std::string& famName = it3.first;
4822 mcIdType famNum = it3.second;
4823 if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
4825 // Is it used by a group of the current mesh or a group from a previous mesh?
4826 // If not, this is OK (typically -1 familly).
4829 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4830 for(const auto& it4 : locMap2)
4832 const auto& famLst = it4.second;
4833 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4834 { used = true; break; }
4836 // Previous meshes ...
4838 for(const auto& it4 : grpFamMap)
4840 const auto& famLst = it4.second;
4841 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4842 { used = true; break; }
4846 { // Generate a new family name, and a new family number
4847 fam_conflict = true;
4848 std::ostringstream oss;
4849 oss << "Family_" << --min_fam_num; // New ID
4850 std::string new_name(oss.str());
4851 substitute[famName] = new_name;
4852 substituteN[famNum] = min_fam_num;
4853 famNumMap[new_name] = min_fam_num;
4854 famNumMap_rev[min_fam_num] = new_name;
4857 famNumMap[famName] = famNum;
4858 famNumMap_rev[famNum] = famName;
4861 for(const auto& level : levs)
4863 MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
4864 m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
4865 m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
4867 // Family field - substitute new family number if needed:
4870 DataArrayIdType* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
4871 mem_cleanup.insert(MCAuto<DataArrayIdType>(dai)); // Make sure array will decrRef() at end of method
4872 for (const auto& subN : substituteN)
4873 dai->changeValue(subN.first, subN.second);
4874 m_fam[level].push_back(dai);
4877 m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
4880 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4881 for(const auto& grpItem : locMap2)
4883 const std::string& grpName = grpItem.first;
4884 std::vector<std::string> famLst;
4885 // Substitute family name in group description if needed:
4888 famLst = grpItem.second;
4889 for (const auto& sub : substitute)
4890 std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
4893 famLst = grpItem.second;
4895 // Potentially merge groups (if same name):
4896 const auto& it = grpFamMap.find(grpName);
4897 if (it != grpFamMap.end())
4899 // Group already exists, merge should be done. Normally we whould never
4900 // have twice the same family name in famLstCur and famLst since we dealt with family number
4901 // conflict just above ...
4902 std::vector<std::string>& famLstCur = (*it).second;
4903 famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
4906 grpFamMap[grpName] = famLst;
4909 // Easy part : nodes
4910 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4911 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4912 ret->setCoords(coo);
4913 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayIdType *)0)==fam_coos.end())
4915 MCAuto<DataArrayIdType> fam_coo(DataArrayIdType::Aggregate(fam_coos));
4916 ret->setFamilyFieldArr(1,fam_coo);
4918 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayIdType *)0)==num_coos.end())
4920 MCAuto<DataArrayIdType> num_coo(DataArrayIdType::Aggregate(num_coos));
4921 ret->setRenumFieldArr(1,num_coo);
4924 for(const auto& level : levs)
4926 auto it2(m_mesh.find(level));
4927 if(it2==m_mesh.end())
4928 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4929 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4930 mesh->setCoords(coo); mesh->setName(ref->getName());
4931 MCAuto<DataArrayIdType> renum(mesh->sortCellsInMEDFileFrmt());
4932 ret->setMeshAtLevel(level,mesh);
4933 auto it3(m_fam.find(level)),it4(m_renum.find(level));
4934 if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
4935 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
4936 if(it4==m_renum.end())
4937 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
4938 // Set new family field if it was defined for all input meshes
4939 const std::vector<const DataArrayIdType *>& fams((*it3).second);
4940 if(std::find(fams.begin(),fams.end(),(const DataArrayIdType *)0)==fams.end())
4942 MCAuto<DataArrayIdType> famm(DataArrayIdType::Aggregate(fams));
4943 famm->renumberInPlace(renum->begin());
4944 ret->setFamilyFieldArr(level,famm);
4946 // Set optional number field if defined for all input meshes:
4947 const std::vector<const DataArrayIdType *>& renums((*it4).second);
4948 if(std::find(renums.begin(),renums.end(),(const DataArrayIdType *)0)==renums.end())
4950 MCAuto<DataArrayIdType> renumm(DataArrayIdType::Aggregate(renums));
4951 renumm->renumberInPlace(renum->begin());
4952 ret->setRenumFieldArr(level,renumm);
4956 ret->setFamilyInfo(famNumMap);
4957 ret->setGroupInfo(grpFamMap);
4958 ret->setName(ref->getName());
4962 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4964 if(getMeshDimension()!=3)
4965 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4966 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4967 if(m3D.isNull() || m2D.isNull())
4968 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4969 mcIdType zeId(std::numeric_limits<med_int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4970 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4974 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4976 clearNonDiscrAttributes();
4977 forceComputationOfParts();
4978 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4979 std::vector<mcIdType> layer0;
4980 layer0.push_back(getAxisType());//0 i
4981 layer0.push_back(_order); //1 i
4982 layer0.push_back(_iteration);//2 i
4983 layer0.push_back(getSpaceDimension());//3 i
4984 tinyDouble.push_back(_time);//0 d
4985 tinyStr.push_back(_name);//0 s
4986 tinyStr.push_back(_desc_name);//1 s
4987 for(int i=0;i<getSpaceDimension();i++)
4988 tinyStr.push_back(_coords->getInfoOnComponent(i));
4989 layer0.push_back(ToIdType(_families.size()));//4 i <- key info aa layer#0
4990 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
4992 tinyStr.push_back((*it).first);
4993 layer0.push_back((*it).second);
4995 layer0.push_back((mcIdType)_groups.size());//4+aa i <- key info bb layer#0
4996 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4998 layer0.push_back(ToIdType((*it0).second.size()));
4999 tinyStr.push_back((*it0).first);
5000 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
5001 tinyStr.push_back(*it1);
5003 // sizeof(layer0)==4+aa+1+bb layer#0
5004 bigArrayD=_coords;// 0 bd
5005 bigArraysI.push_back(_fam_coords);// 0 bi
5006 bigArraysI.push_back(_num_coords);// 1 bi
5007 const PartDefinition *pd(_part_coords);
5009 layer0.push_back(-1);
5012 std::vector<mcIdType> tmp0;
5013 pd->serialize(tmp0,bigArraysI);
5014 tinyInt.push_back(ToIdType(tmp0.size()));
5015 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
5018 std::vector<mcIdType> layer1;
5019 std::vector<int> levs(getNonEmptyLevels());
5020 layer1.push_back((mcIdType)levs.size());// 0 i <- key
5021 layer1.insert(layer1.end(),levs.begin(),levs.end());
5022 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
5024 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
5025 lev->serialize(layer1,bigArraysI);
5027 // put layers all together.
5028 tinyInt.push_back(ToIdType(layer0.size()));
5029 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
5030 tinyInt.push_back(ToIdType(layer1.size()));
5031 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
5034 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr,
5035 std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5037 mcIdType sz0(tinyInt[0]);
5038 std::vector<mcIdType> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
5039 mcIdType sz1(tinyInt[sz0+1]);
5040 std::vector<mcIdType> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
5042 std::reverse(layer0.begin(),layer0.end());
5043 std::reverse(layer1.begin(),layer1.end());
5044 std::reverse(tinyDouble.begin(),tinyDouble.end());
5045 std::reverse(tinyStr.begin(),tinyStr.end());
5046 std::reverse(bigArraysI.begin(),bigArraysI.end());
5048 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
5049 _order=FromIdType<int>(layer0.back()); layer0.pop_back();
5050 _iteration=FromIdType<int>(layer0.back()); layer0.pop_back();
5051 mcIdType spaceDim(layer0.back()); layer0.pop_back();
5052 _time=tinyDouble.back(); tinyDouble.pop_back();
5053 _name=tinyStr.back(); tinyStr.pop_back();
5054 _desc_name=tinyStr.back(); tinyStr.pop_back();
5055 _coords=bigArrayD; _coords->rearrange(spaceDim);
5056 for(int i=0;i<spaceDim;i++)
5058 _coords->setInfoOnComponent(i,tinyStr.back());
5061 mcIdType nbOfFams(layer0.back()); layer0.pop_back();
5063 for(mcIdType i=0;i<nbOfFams;i++)
5065 _families[tinyStr.back()]=layer0.back();
5066 tinyStr.pop_back(); layer0.pop_back();
5068 mcIdType nbGroups(layer0.back()); layer0.pop_back();
5070 for(mcIdType i=0;i<nbGroups;i++)
5072 std::string grpName(tinyStr.back()); tinyStr.pop_back();
5073 mcIdType nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
5074 std::vector<std::string> fams(nbOfFamsOnGrp);
5075 for(mcIdType j=0;j<nbOfFamsOnGrp;j++)
5077 fams[j]=tinyStr.back(); tinyStr.pop_back();
5079 _groups[grpName]=fams;
5081 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
5082 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
5084 mcIdType isPd(layer0.back()); layer0.pop_back();
5087 std::vector<mcIdType> tmp0(layer0.begin(),layer0.begin()+isPd);
5088 layer0.erase(layer0.begin(),layer0.begin()+isPd);
5089 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
5092 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
5094 mcIdType nbLevs(layer1.back()); layer1.pop_back();
5095 std::vector<mcIdType> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
5097 mcIdType maxLev(-(*std::min_element(levs.begin(),levs.end())));
5098 _ms.resize(maxLev+1);
5099 for(mcIdType i=0;i<nbLevs;i++)
5101 mcIdType lev(levs[i]);
5103 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
5108 * Adds a group of nodes to \a this mesh.
5109 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5110 * The ids should be sorted and different each other (MED file norm).
5112 * \warning this method can alter default "FAMILLE_ZERO" family.
5113 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5115 * \throw If the node coordinates array is not set.
5116 * \throw If \a ids == \c NULL.
5117 * \throw If \a ids->getName() == "".
5118 * \throw If \a ids does not respect the MED file norm.
5119 * \throw If a group with name \a ids->getName() already exists.
5121 void MEDFileUMesh::addNodeGroup(const DataArrayIdType *ids)
5123 const DataArrayDouble *coords(_coords);
5125 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
5126 mcIdType nbOfNodes(coords->getNumberOfTuples());
5127 if(_fam_coords.isNull())
5128 { _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
5130 addGroupUnderground(true,ids,_fam_coords);
5134 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5136 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5137 * The ids should be sorted and different each other (MED file norm).
5139 * \warning this method can alter default "FAMILLE_ZERO" family.
5140 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5142 * \throw If the node coordinates array is not set.
5143 * \throw If \a ids == \c NULL.
5144 * \throw If \a ids->getName() == "".
5145 * \throw If \a ids does not respect the MED file norm.
5146 * \throw If a group with name \a ids->getName() already exists.
5148 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
5150 std::vector<int> levs(getNonEmptyLevelsExt());
5151 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
5153 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
5154 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
5156 if(meshDimRelToMaxExt==1)
5157 { addNodeGroup(ids); return ; }
5158 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
5159 DataArrayIdType *fam(lev->getOrCreateAndGetFamilyField());
5160 addGroupUnderground(false,ids,fam);
5164 * Changes a name of a family specified by its id.
5165 * \param [in] id - the id of the family of interest.
5166 * \param [in] newFamName - the new family name.
5167 * \throw If no family with the given \a id exists.
5169 void MEDFileUMesh::setFamilyNameAttachedOnId(mcIdType id, const std::string& newFamName)
5171 std::string oldName=getFamilyNameGivenId(id);
5172 _families.erase(oldName);
5173 _families[newFamName]=id;
5177 * Removes a mesh of a given dimension.
5178 * \param [in] meshDimRelToMax - the relative dimension of interest.
5179 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
5181 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
5183 std::vector<int> levSet=getNonEmptyLevels();
5184 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
5185 if(it==levSet.end())
5186 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
5187 int pos=(-meshDimRelToMax);
5192 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
5193 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5194 * \param [in] m - the new mesh to set.
5195 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5197 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5198 * another node coordinates array.
5199 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5200 * to the existing meshes of other levels of \a this mesh.
5202 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5204 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5205 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5209 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5210 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5211 * \param [in] m - the new mesh to set.
5212 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5213 * writing \a this mesh in a MED file.
5214 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5216 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5217 * another node coordinates array.
5218 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5219 * to the existing meshes of other levels of \a this mesh.
5221 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5223 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5224 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5227 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5229 dealWithTinyInfo(m);
5230 std::vector<int> levSet=getNonEmptyLevels();
5231 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5233 if((DataArrayDouble *)_coords==0)
5235 DataArrayDouble *c=m->getCoords();
5240 if(m->getCoords()!=_coords)
5241 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5242 int sz=(-meshDimRelToMax)+1;
5243 if(sz>=(int)_ms.size())
5245 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5249 return _ms[-meshDimRelToMax];
5253 * This method allows to set at once the content of different levels in \a this.
5254 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5256 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5257 * \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.
5258 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5260 * \throw If \a there is a null pointer in \a ms.
5261 * \sa MEDFileUMesh::setMeshAtLevel
5263 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5267 const MEDCouplingUMesh *mRef=ms[0];
5269 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5270 std::string name(mRef->getName());
5271 const DataArrayDouble *coo(mRef->getCoords());
5274 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5276 const MEDCouplingUMesh *cur(*it);
5278 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5279 if(coo!=cur->getCoords())
5280 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5281 int mdim=cur->getMeshDimension();
5282 zeDim=std::max(zeDim,mdim);
5283 if(s.find(mdim)!=s.end())
5284 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5286 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5288 int mdim=(*it)->getMeshDimension();
5289 setName((*it)->getName());
5290 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5296 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5297 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5298 * The given meshes must share the same node coordinates array.
5299 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5300 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5301 * create in \a this mesh.
5302 * \throw If \a ms is empty.
5303 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5304 * to the existing meshes of other levels of \a this mesh.
5305 * \throw If the meshes in \a ms do not share the same node coordinates array.
5306 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5307 * of the given meshes.
5308 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5309 * \throw If names of some meshes in \a ms are equal.
5310 * \throw If \a ms includes a mesh with an empty name.
5312 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5315 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5316 int sz=(-meshDimRelToMax)+1;
5317 if(sz>=(int)_ms.size())
5319 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5320 DataArrayDouble *coo=checkMultiMesh(ms);
5321 if((DataArrayDouble *)_coords==0)
5327 if((DataArrayDouble *)_coords!=coo)
5328 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5329 std::vector<DataArrayIdType *> corr;
5330 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5331 std::vector< MCAuto<DataArrayIdType> > corr3(corr.begin(),corr.end());
5332 setMeshAtLevel(meshDimRelToMax,m,renum);
5333 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5334 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5338 * Creates groups at a given level in \a this mesh from a sequence of
5339 * meshes each representing a group.
5340 * The given meshes must share the same node coordinates array.
5341 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5342 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5343 * create in \a this mesh.
5344 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5346 * \throw If \a ms is empty.
5347 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5348 * to the existing meshes of other levels of \a this mesh.
5349 * \throw If the meshes in \a ms do not share the same node coordinates array.
5350 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5351 * of the given meshes.
5352 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5353 * \throw If names of some meshes in \a ms are equal.
5354 * \throw If \a ms includes a mesh with an empty name.
5356 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5359 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5360 int sz=(-meshDimRelToMax)+1;
5361 if(sz>=(int)_ms.size())
5363 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5364 DataArrayDouble *coo=checkMultiMesh(ms);
5365 if((DataArrayDouble *)_coords==0)
5371 if((DataArrayDouble *)_coords!=coo)
5372 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5373 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5374 std::vector< MCAuto<DataArrayIdType> > corr(ms.size());
5376 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5378 DataArrayIdType *arr=0;
5379 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5383 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5384 throw INTERP_KERNEL::Exception(oss.str().c_str());
5387 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5388 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5391 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5393 const DataArrayDouble *ret=ms[0]->getCoords();
5394 int mdim=ms[0]->getMeshDimension();
5395 for(unsigned int i=1;i<ms.size();i++)
5397 ms[i]->checkConsistencyLight();
5398 if(ms[i]->getCoords()!=ret)
5399 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5400 if(ms[i]->getMeshDimension()!=mdim)
5401 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5403 return const_cast<DataArrayDouble *>(ret);
5407 * Sets the family field of a given relative dimension.
5408 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5409 * the family field is set.
5410 * \param [in] famArr - the array of the family field.
5411 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5412 * \throw If \a famArr has an invalid size.
5414 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5416 if(meshDimRelToMaxExt==1)
5423 DataArrayDouble *coo(_coords);
5425 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5426 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5427 _fam_coords.takeRef(famArr);
5430 if(meshDimRelToMaxExt>1)
5431 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5432 int traducedRk=-meshDimRelToMaxExt;
5433 if(traducedRk>=(int)_ms.size())
5434 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5435 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5436 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5437 return _ms[traducedRk]->setFamilyArr(famArr);
5441 * Sets the optional numbers of mesh entities of a given dimension.
5442 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5443 * \param [in] renumArr - the array of the numbers.
5444 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5445 * \throw If \a renumArr has an invalid size.
5447 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5449 if(meshDimRelToMaxExt==1)
5453 _num_coords.nullify();
5454 _rev_num_coords.nullify();
5457 if(_coords.isNull())
5458 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5459 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5460 _num_coords.takeRef(renumArr);
5464 if(meshDimRelToMaxExt>1)
5465 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5466 int traducedRk=-meshDimRelToMaxExt;
5467 if(traducedRk>=(int)_ms.size())
5468 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5469 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5470 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5471 return _ms[traducedRk]->setRenumArr(renumArr);
5475 * Sets the optional names of mesh entities of a given dimension.
5476 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5477 * \param [in] nameArr - the array of the names.
5478 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5479 * \throw If \a nameArr has an invalid size.
5481 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5483 if(meshDimRelToMaxExt==1)
5490 DataArrayDouble *coo(_coords);
5492 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5493 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5494 _name_coords.takeRef(nameArr);
5497 if(meshDimRelToMaxExt>1)
5498 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5499 int traducedRk=-meshDimRelToMaxExt;
5500 if(traducedRk>=(int)_ms.size())
5501 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5502 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5503 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5504 return _ms[traducedRk]->setNameArr(nameArr);
5507 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
5509 if(meshDimRelToMaxExt!=1)
5510 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5512 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5513 _global_num_coords.takeRef(globalNumArr);
5516 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5518 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5519 if((const MEDFileUMeshSplitL1 *)(*it))
5520 (*it)->synchronizeTinyInfo(*this);
5524 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5526 void MEDFileUMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
5528 DataArrayIdType *arr=_fam_coords;
5530 arr->changeValue(oldId,newId);
5531 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5533 MEDFileUMeshSplitL1 *sp=(*it);
5536 sp->changeFamilyIdArr(oldId,newId);
5541 std::list< MCAuto<DataArrayIdType> > MEDFileUMesh::getAllNonNullFamilyIds() const
5543 std::list< MCAuto<DataArrayIdType> > ret;
5544 const DataArrayIdType *da(_fam_coords);
5546 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5547 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5549 const MEDFileUMeshSplitL1 *elt(*it);
5552 da=elt->getFamilyField();
5554 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5560 void MEDFileUMesh::computeRevNum() const
5562 if(_num_coords.isNotNull())
5565 mcIdType maxValue=_num_coords->getMaxValue(pos);
5566 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5570 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5572 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5575 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5577 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5578 ret.push_back((const DataArrayIdType *)_fam_nodes);
5579 ret.push_back((const DataArrayIdType *)_num_nodes);
5580 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5581 ret.push_back((const DataArrayIdType *)_fam_cells);
5582 ret.push_back((const DataArrayIdType *)_num_cells);
5583 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5584 ret.push_back((const DataArrayIdType *)_fam_faces);
5585 ret.push_back((const DataArrayIdType *)_num_faces);
5586 ret.push_back((const DataArrayIdType *)_rev_num_nodes);
5587 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5588 ret.push_back((const DataArrayIdType *)_rev_num_cells);
5589 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5593 mcIdType MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5595 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5596 if((const DataArrayIdType *)_fam_nodes)
5598 mcIdType val=_fam_nodes->getMaxValue(tmp);
5599 ret=std::max(ret,std::abs(val));
5601 if((const DataArrayIdType *)_fam_cells)
5603 mcIdType val=_fam_cells->getMaxValue(tmp);
5604 ret=std::max(ret,std::abs(val));
5606 if((const DataArrayIdType *)_fam_faces)
5608 mcIdType val=_fam_faces->getMaxValue(tmp);
5609 ret=std::max(ret,std::abs(val));
5614 mcIdType MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5616 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5617 if((const DataArrayIdType *)_fam_nodes)
5619 mcIdType val=_fam_nodes->getMaxValue(tmp);
5620 ret=std::max(ret,val);
5622 if((const DataArrayIdType *)_fam_cells)
5624 mcIdType val=_fam_cells->getMaxValue(tmp);
5625 ret=std::max(ret,val);
5627 if((const DataArrayIdType *)_fam_faces)
5629 mcIdType val=_fam_faces->getMaxValue(tmp);
5630 ret=std::max(ret,val);
5635 mcIdType MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5637 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
5638 if((const DataArrayIdType *)_fam_nodes)
5640 mcIdType val=_fam_nodes->getMinValue(tmp);
5641 ret=std::min(ret,val);
5643 if((const DataArrayIdType *)_fam_cells)
5645 mcIdType val=_fam_cells->getMinValue(tmp);
5646 ret=std::min(ret,val);
5648 if((const DataArrayIdType *)_fam_faces)
5650 mcIdType val=_fam_faces->getMinValue(tmp);
5651 ret=std::min(ret,val);
5656 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5658 if(!MEDFileMesh::isEqual(other,eps,what))
5660 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5663 what="Mesh types differ ! This is structured and other is NOT !";
5666 const DataArrayIdType *famc1=_fam_nodes;
5667 const DataArrayIdType *famc2=otherC->_fam_nodes;
5668 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5670 what="Mismatch of families arr on nodes ! One is defined and not other !";
5675 bool ret=famc1->isEqual(*famc2);
5678 what="Families arr on nodes differ !";
5683 famc2=otherC->_fam_cells;
5684 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5686 what="Mismatch of families arr on cells ! One is defined and not other !";
5691 bool ret=famc1->isEqual(*famc2);
5694 what="Families arr on cells differ !";
5699 famc2=otherC->_fam_faces;
5700 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5702 what="Mismatch of families arr on faces ! One is defined and not other !";
5707 bool ret=famc1->isEqual(*famc2);
5710 what="Families arr on faces differ !";
5715 famc2=otherC->_num_nodes;
5716 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5718 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5723 bool ret=famc1->isEqual(*famc2);
5726 what="Numbering arr on nodes differ !";
5731 famc2=otherC->_num_cells;
5732 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5734 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5739 bool ret=famc1->isEqual(*famc2);
5742 what="Numbering arr on cells differ !";
5747 famc2=otherC->_num_faces;
5748 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5750 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5755 bool ret=famc1->isEqual(*famc2);
5758 what="Numbering arr on faces differ !";
5762 const DataArrayAsciiChar *d1=_names_cells;
5763 const DataArrayAsciiChar *d2=otherC->_names_cells;
5764 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5766 what="Mismatch of naming arr on cells ! One is defined and not other !";
5771 bool ret=d1->isEqual(*d2);
5774 what="Naming arr on cells differ !";
5779 d2=otherC->_names_faces;
5780 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5782 what="Mismatch of naming arr on faces ! One is defined and not other !";
5787 bool ret=d1->isEqual(*d2);
5790 what="Naming arr on faces differ !";
5795 d2=otherC->_names_nodes;
5796 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5798 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5803 bool ret=d1->isEqual(*d2);
5806 what="Naming arr on nodes differ !";
5813 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5815 MEDFileMesh::clearNonDiscrAttributes();
5816 const DataArrayIdType *tmp=_fam_nodes;
5818 (const_cast<DataArrayIdType *>(tmp))->setName("");
5821 (const_cast<DataArrayIdType *>(tmp))->setName("");
5824 (const_cast<DataArrayIdType *>(tmp))->setName("");
5827 (const_cast<DataArrayIdType *>(tmp))->setName("");
5830 (const_cast<DataArrayIdType *>(tmp))->setName("");
5833 (const_cast<DataArrayIdType *>(tmp))->setName("");
5837 * Returns ids of mesh entities contained in given families of a given dimension.
5838 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5840 * \param [in] fams - the names of the families of interest.
5841 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5842 * returned instead of ids.
5843 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
5844 * numbers, if available and required, of mesh entities of the families. The caller
5845 * is to delete this array using decrRef() as it is no more needed.
5846 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5848 DataArrayIdType *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5850 std::vector<mcIdType> famIds(getFamiliesIds(fams));
5851 switch(meshDimRelToMaxExt)
5855 if((const DataArrayIdType *)_fam_nodes)
5857 MCAuto<DataArrayIdType> da;
5859 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5861 da=_fam_nodes->findIdsEqualList(0,0);
5863 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5868 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5873 if((const DataArrayIdType *)_fam_cells)
5875 MCAuto<DataArrayIdType> da;
5877 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5879 da=_fam_cells->findIdsEqualList(0,0);
5881 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5886 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5891 if((const DataArrayIdType *)_fam_faces)
5893 MCAuto<DataArrayIdType> da;
5895 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5897 da=_fam_faces->findIdsEqualList(0,0);
5899 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5904 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5908 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5910 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5914 * Sets the family field of a given relative dimension.
5915 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5916 * the family field is set.
5917 * \param [in] famArr - the array of the family field.
5918 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5919 * \throw If \a famArr has an invalid size.
5920 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5922 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5924 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5926 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5927 switch(meshDimRelToMaxExt)
5931 mcIdType nbCells(mesh->getNumberOfCells());
5933 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5939 mcIdType nbNodes(mesh->getNumberOfNodes());
5941 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5947 mcIdType nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5949 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5954 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5961 * Sets the optional numbers of mesh entities of a given dimension.
5962 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5963 * \param [in] renumArr - the array of the numbers.
5964 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5965 * \throw If \a renumArr has an invalid size.
5966 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5968 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5970 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5972 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5973 switch(meshDimRelToMaxExt)
5977 mcIdType nbCells=mesh->getNumberOfCells();
5978 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5979 _num_cells=renumArr;
5984 mcIdType nbNodes=mesh->getNumberOfNodes();
5985 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5986 _num_nodes=renumArr;
5991 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5992 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5993 _num_faces=renumArr;
5997 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
6000 renumArr->incrRef();
6004 * Sets the optional names of mesh entities of a given dimension.
6005 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6006 * \param [in] nameArr - the array of the names.
6007 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6008 * \throw If \a nameArr has an invalid size.
6010 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
6012 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
6014 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
6015 switch(meshDimRelToMaxExt)
6019 mcIdType nbCells=mesh->getNumberOfCells();
6020 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
6021 _names_cells=nameArr;
6026 mcIdType nbNodes=mesh->getNumberOfNodes();
6027 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
6028 _names_nodes=nameArr;
6033 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6034 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
6035 _names_faces=nameArr;
6038 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6044 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
6046 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
6050 * Adds a group of nodes to \a this mesh.
6051 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6052 * The ids should be sorted and different each other (MED file norm).
6054 * \warning this method can alter default "FAMILLE_ZERO" family.
6055 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6057 * \throw If the node coordinates array is not set.
6058 * \throw If \a ids == \c NULL.
6059 * \throw If \a ids->getName() == "".
6060 * \throw If \a ids does not respect the MED file norm.
6061 * \throw If a group with name \a ids->getName() already exists.
6063 void MEDFileStructuredMesh::addNodeGroup(const DataArrayIdType *ids)
6069 * Adds a group of nodes/cells/faces/edges to \a this mesh.
6071 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6072 * The ids should be sorted and different each other (MED file norm).
6074 * \warning this method can alter default "FAMILLE_ZERO" family.
6075 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6077 * \throw If the node coordinates array is not set.
6078 * \throw If \a ids == \c NULL.
6079 * \throw If \a ids->getName() == "".
6080 * \throw If \a ids does not respect the MED file norm.
6081 * \throw If a group with name \a ids->getName() already exists.
6083 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
6085 DataArrayIdType *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
6086 addGroupUnderground(false,ids,fam);
6091 * Returns the family field for mesh entities of a given dimension.
6092 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6093 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6094 * each mesh entity belongs to. It can be \c NULL.
6095 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6097 const DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
6099 switch(meshDimRelToMaxExt)
6108 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6113 * Returns the family field for mesh entities of a given dimension.
6114 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6115 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6116 * each mesh entity belongs to. It can be \c NULL.
6117 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6119 DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
6121 switch(meshDimRelToMaxExt)
6130 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6135 * Returns the optional numbers of mesh entities of a given dimension.
6136 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6137 * \return const DataArrayIdType * - the array of the entity numbers.
6138 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6139 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6141 const DataArrayIdType *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
6143 switch(meshDimRelToMaxExt)
6152 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6157 * Returns the optional numbers of mesh entities of a given dimension transformed using
6158 * DataArrayIdType::invertArrayN2O2O2N().
6159 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6160 * \return const DataArrayIdType * - the array of the entity numbers transformed using
6161 * DataArrayIdType::invertArrayN2O2O2N().
6162 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6163 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6165 const DataArrayIdType *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
6167 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
6168 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
6169 if(meshDimRelToMaxExt==0)
6171 if((const DataArrayIdType *)_num_cells)
6174 mcIdType maxValue=_num_cells->getMaxValue(pos);
6175 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
6176 return _rev_num_cells;
6179 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
6183 if((const DataArrayIdType *)_num_nodes)
6186 mcIdType maxValue=_num_nodes->getMaxValue(pos);
6187 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
6188 return _rev_num_nodes;
6191 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6195 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6197 switch(meshDimRelToMaxExt)
6200 return _names_cells;
6202 return _names_nodes;
6204 return _names_faces;
6206 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6210 MCAuto<DataArrayIdType> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6212 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6216 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6217 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6219 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6221 std::vector<int> ret(1);
6226 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6227 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6229 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6231 std::vector<int> ret(2);
6237 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6239 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6241 std::vector<int> ret;
6242 const DataArrayIdType *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6253 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6255 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6257 std::vector<int> ret;
6258 const DataArrayIdType *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6269 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6271 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6273 std::vector<int> ret;
6274 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6285 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6287 bool MEDFileStructuredMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
6289 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6293 void MEDFileStructuredMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
6295 DataArrayIdType *arr=_fam_nodes;
6297 arr->changeValue(oldId,newId);
6300 arr->changeValue(oldId,newId);
6303 arr->changeValue(oldId,newId);
6306 std::list< MCAuto<DataArrayIdType> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6308 std::list< MCAuto<DataArrayIdType> > ret;
6309 const DataArrayIdType *da(_fam_nodes);
6311 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6314 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6317 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6321 void MEDFileStructuredMesh::deepCpyAttributes()
6323 if((const DataArrayIdType*)_fam_nodes)
6324 _fam_nodes=_fam_nodes->deepCopy();
6325 if((const DataArrayIdType*)_num_nodes)
6326 _num_nodes=_num_nodes->deepCopy();
6327 if((const DataArrayAsciiChar*)_names_nodes)
6328 _names_nodes=_names_nodes->deepCopy();
6329 if((const DataArrayIdType*)_fam_cells)
6330 _fam_cells=_fam_cells->deepCopy();
6331 if((const DataArrayIdType*)_num_cells)
6332 _num_cells=_num_cells->deepCopy();
6333 if((const DataArrayAsciiChar*)_names_cells)
6334 _names_cells=_names_cells->deepCopy();
6335 if((const DataArrayIdType*)_fam_faces)
6336 _fam_faces=_fam_faces->deepCopy();
6337 if((const DataArrayIdType*)_num_faces)
6338 _num_faces=_num_faces->deepCopy();
6339 if((const DataArrayAsciiChar*)_names_faces)
6340 _names_faces=_names_faces->deepCopy();
6341 if((const DataArrayIdType*)_rev_num_nodes)
6342 _rev_num_nodes=_rev_num_nodes->deepCopy();
6343 if((const DataArrayIdType*)_rev_num_cells)
6344 _rev_num_cells=_rev_num_cells->deepCopy();
6348 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6350 * \return a pointer to cartesian mesh that need to be managed by the caller.
6351 * \warning the returned pointer has to be managed by the caller.
6355 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6356 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6357 * \param [in] renum - it must be \c false.
6358 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6359 * delete using decrRef() as it is no more needed.
6361 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6365 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6366 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6367 switch(meshDimRelToMax)
6373 return const_cast<MEDCouplingStructuredMesh *>(m);
6378 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6379 buildMinusOneImplicitPartIfNeeded();
6380 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6386 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6390 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6392 std::vector<mcIdType> ret;
6393 const DataArrayIdType *famCells(_fam_cells),*famFaces(_fam_faces);
6394 if(famCells && famCells->presenceOfValue(ret))
6396 if(famFaces && famFaces->presenceOfValue(ret))
6401 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6403 std::vector<mcIdType> ret(getFamsNonEmptyLevels(fams));
6404 const DataArrayIdType *famNodes(_fam_nodes);
6405 if(famNodes && famNodes->presenceOfValue(ret))
6411 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6412 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6413 * \return mcIdType - the number of entities.
6414 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6416 mcIdType MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6418 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6420 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6421 switch(meshDimRelToMaxExt)
6424 return cmesh->getNumberOfCells();
6426 return cmesh->getNumberOfNodes();
6428 return cmesh->getNumberOfCellsOfSubLevelMesh();
6430 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6434 mcIdType MEDFileStructuredMesh::getNumberOfNodes() const
6436 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6438 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6439 return cmesh->getNumberOfNodes();
6442 mcIdType MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6444 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6446 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6447 switch(meshDimRelToMaxExt)
6450 return cmesh->getNumberOfCells();
6452 return cmesh->getNumberOfCellsOfSubLevelMesh();
6454 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6458 bool MEDFileStructuredMesh::hasImplicitPart() const
6464 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6466 mcIdType MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6468 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6469 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6472 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6473 if(cm.getReverseExtrudedType()!=gt)
6474 throw INTERP_KERNEL::Exception(MSG);
6475 buildImplicitPart();
6476 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6480 if(gt!=zeFaceMesh->getCellModelEnum())
6481 throw INTERP_KERNEL::Exception(MSG);
6482 return zeFaceMesh->getNumberOfCells();
6486 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6488 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6490 buildImplicitPart();
6493 void MEDFileStructuredMesh::buildImplicitPart() const
6495 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6497 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6498 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6501 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6503 _faces_if_necessary=0;
6507 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6508 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6510 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6512 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6515 return _faces_if_necessary;
6518 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6520 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6522 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6523 switch(meshDimRelToMax)
6527 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6532 int mdim(cmesh->getMeshDimension());
6534 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6535 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6539 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6543 mcIdType MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6545 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6548 return getNumberOfCellsAtLevel(0);
6551 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6553 if(st.getNumberOfItems()!=1)
6554 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 !");
6555 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6556 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6557 if(getNumberOfNodes()!=(mcIdType)nodesFetched.size())
6558 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6559 if(st[0].getPflName().empty())
6561 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6564 const DataArrayIdType *arr(globs->getProfile(st[0].getPflName()));
6565 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6566 mcIdType sz(ToIdType(nodesFetched.size()));
6567 for(const mcIdType *work=arr->begin();work!=arr->end();work++)
6569 std::vector<mcIdType> conn;
6570 cmesh->getNodeIdsOfCell(*work,conn);
6571 for(std::vector<mcIdType>::const_iterator it=conn.begin();it!=conn.end();it++)
6572 if(*it>=0 && *it<sz)
6573 nodesFetched[*it]=true;
6575 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6579 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6581 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6585 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6586 MCAuto<DataArrayIdType>& famCells, MCAuto<DataArrayIdType>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6588 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6589 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6590 mcIdType nbOfElt(0);
6591 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6594 if(!mrs || mrs->isCellFamilyFieldReading())
6596 MCAuto<DataArrayMedInt> miFamCells=DataArrayMedInt::New();
6597 miFamCells->alloc(nbOfElt,1);
6598 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miFamCells->getPointer()));
6599 famCells = FromMedIntArray<mcIdType>( miFamCells );
6602 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6605 if(!mrs || mrs->isCellNumFieldReading())
6607 MCAuto<DataArrayMedInt> miNumCells=DataArrayMedInt::New();
6608 miNumCells->alloc(nbOfElt,1);
6609 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miNumCells->getPointer()));
6610 numCells = FromMedIntArray<mcIdType>( miNumCells );
6613 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6616 if(!mrs || mrs->isCellNameFieldReading())
6618 namesCells=DataArrayAsciiChar::New();
6619 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6620 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6621 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6626 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6628 setName(strm->getName());
6629 setDescription(strm->getDescription());
6630 setUnivName(strm->getUnivName());
6631 setIteration(strm->getIteration());
6632 setOrder(strm->getOrder());
6633 setTimeValue(strm->getTime());
6634 setTimeUnit(strm->getTimeUnit());
6635 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6636 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6637 mcIdType nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6640 if(!mrs || mrs->isNodeFamilyFieldReading())
6642 mcIdType nbNodes(getNumberOfNodes());
6644 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6645 MCAuto<DataArrayMedInt> miFamNodes=DataArrayMedInt::New();
6646 miFamNodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6647 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...
6648 miFamNodes->fillWithZero();
6649 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miFamNodes->getPointer()));
6650 _fam_nodes = FromMedIntArray<mcIdType>( miFamNodes );
6653 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6656 if(!mrs || mrs->isNodeNumFieldReading())
6658 MCAuto<DataArrayMedInt> miNumNodes=DataArrayMedInt::New();
6659 miNumNodes->alloc(nbOfElt,1);
6660 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miNumNodes->getPointer()));
6661 _num_nodes = FromMedIntArray<mcIdType>( miNumNodes );
6664 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6667 if(!mrs || mrs->isNodeNameFieldReading())
6669 _names_nodes=DataArrayAsciiChar::New();
6670 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6671 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6672 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6675 int meshDim(getStructuredMesh()->getMeshDimension());
6676 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6678 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6681 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6683 int meshDim(getStructuredMesh()->getMeshDimension());
6684 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6686 if((const DataArrayIdType *)_fam_cells)
6687 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_fam_cells->getNumberOfTuples()),ToMedIntArray(_fam_cells)->getConstPointer()));
6688 if((const DataArrayIdType *)_fam_faces)
6689 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_fam_faces->getNumberOfTuples()),ToMedIntArray(_fam_faces)->getConstPointer()));
6690 if((const DataArrayIdType *)_fam_nodes)
6691 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_fam_nodes->getNumberOfTuples()),ToMedIntArray(_fam_nodes)->getConstPointer()));
6692 if((const DataArrayIdType *)_num_cells)
6693 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_num_cells->getNumberOfTuples()),ToMedIntArray(_num_cells)->getConstPointer()));
6694 if((const DataArrayIdType *)_num_faces)
6695 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_num_faces->getNumberOfTuples()),ToMedIntArray(_num_faces)->getConstPointer()));
6696 if((const DataArrayIdType *)_num_nodes)
6697 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_num_nodes->getNumberOfTuples()),ToMedIntArray(_num_nodes)->getConstPointer()));
6698 if((const DataArrayAsciiChar *)_names_cells)
6700 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6702 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6703 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6704 throw INTERP_KERNEL::Exception(oss.str().c_str());
6706 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_names_cells->getNumberOfTuples()),_names_cells->getConstPointer()));
6708 if((const DataArrayAsciiChar *)_names_faces)
6710 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6712 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6713 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6714 throw INTERP_KERNEL::Exception(oss.str().c_str());
6716 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_names_faces->getNumberOfTuples()),_names_faces->getConstPointer()));
6718 if((const DataArrayAsciiChar *)_names_nodes)
6720 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6722 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6723 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6724 throw INTERP_KERNEL::Exception(oss.str().c_str());
6726 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_names_nodes->getNumberOfTuples()),_names_nodes->getConstPointer()));
6729 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6733 * Returns an empty instance of MEDFileCMesh.
6734 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6735 * mesh using decrRef() as it is no more needed.
6737 MEDFileCMesh *MEDFileCMesh::New()
6739 return new MEDFileCMesh;
6743 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6744 * file. The first mesh in the file is loaded.
6745 * \param [in] fileName - the name of MED file to read.
6746 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6747 * mesh using decrRef() as it is no more needed.
6748 * \throw If the file is not readable.
6749 * \throw If there is no meshes in the file.
6750 * \throw If the mesh in the file is not a Cartesian one.
6752 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6754 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6755 return New(fid,mrs);
6758 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6760 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6764 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6765 * file. The mesh to load is specified by its name and numbers of a time step and an
6767 * \param [in] fileName - the name of MED file to read.
6768 * \param [in] mName - the name of the mesh to read.
6769 * \param [in] dt - the number of a time step.
6770 * \param [in] it - the number of an iteration.
6771 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6772 * mesh using decrRef() as it is no more needed.
6773 * \throw If the file is not readable.
6774 * \throw If there is no mesh with given attributes in the file.
6775 * \throw If the mesh in the file is not a Cartesian one.
6777 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6779 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6780 return New(fid,mName,dt,it,mrs);
6783 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6785 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6788 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6790 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6793 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6795 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6796 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6801 * Returns the dimension on cells in \a this mesh.
6802 * \return int - the mesh dimension.
6803 * \throw If there are no cells in this mesh.
6805 int MEDFileCMesh::getMeshDimension() const
6807 if(!((const MEDCouplingCMesh*)_cmesh))
6808 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6809 return _cmesh->getMeshDimension();
6813 * Returns the dimension on nodes in \a this mesh.
6814 * \return int - the space dimension.
6815 * \throw If there are no cells in this mesh.
6817 int MEDFileCMesh::getSpaceDimension() const
6819 if(!((const MEDCouplingCMesh*)_cmesh))
6820 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6821 return _cmesh->getSpaceDimension();
6825 * Returns a string describing \a this mesh.
6826 * \return std::string - the mesh information string.
6828 std::string MEDFileCMesh::simpleRepr() const
6830 return MEDFileStructuredMesh::simpleRepr();
6834 * Returns a full textual description of \a this mesh.
6835 * \return std::string - the string holding the mesh description.
6837 std::string MEDFileCMesh::advancedRepr() const
6839 return simpleRepr();
6842 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6844 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6848 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6850 return new MEDFileCMesh;
6853 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6855 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6856 ret->deepCpyEquivalences(*this);
6857 if((const MEDCouplingCMesh*)_cmesh)
6858 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6859 ret->deepCpyAttributes();
6864 * Checks if \a this and another mesh are equal.
6865 * \param [in] other - the mesh to compare with.
6866 * \param [in] eps - a precision used to compare real values.
6867 * \param [in,out] what - the string returning description of unequal data.
6868 * \return bool - \c true if the meshes are equal, \c false, else.
6870 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6872 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6874 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6877 what="Mesh types differ ! This is cartesian and other is NOT !";
6880 clearNonDiscrAttributes();
6881 otherC->clearNonDiscrAttributes();
6882 const MEDCouplingCMesh *coo1=_cmesh;
6883 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6884 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6886 what="Mismatch of cartesian meshes ! One is defined and not other !";
6891 bool ret=coo1->isEqual(coo2,eps);
6894 what="cartesian meshes differ !";
6902 * Clears redundant attributes of incorporated data arrays.
6904 void MEDFileCMesh::clearNonDiscrAttributes() const
6906 MEDFileStructuredMesh::clearNonDiscrAttributes();
6907 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6910 MEDFileCMesh::MEDFileCMesh()
6914 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6917 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6919 catch(INTERP_KERNEL::Exception& e)
6924 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6926 MEDCoupling::MEDCouplingMeshType meshType;
6929 MEDCoupling::MEDCouplingAxisType axType;
6930 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6931 if(meshType!=CARTESIAN)
6933 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6934 throw INTERP_KERNEL::Exception(oss.str().c_str());
6936 MEDFileCMeshL2 loaderl2;
6937 loaderl2.loadAll(fid,mid,mName,dt,it);
6938 setAxisType(axType);
6939 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6942 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6946 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6947 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6949 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6951 synchronizeTinyInfoOnLeaves();
6955 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6957 synchronizeTinyInfoOnLeaves();
6962 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6963 * \param [in] m - the new MEDCouplingCMesh to refer to.
6964 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6967 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6969 dealWithTinyInfo(m);
6975 MEDFileMesh *MEDFileCMesh::cartesianize() const
6977 if(getAxisType()==AX_CART)
6980 return const_cast<MEDFileCMesh *>(this);
6984 const MEDCouplingCMesh *cmesh(getMesh());
6986 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6987 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6988 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6989 clmesh->setCoords(coords);
6990 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6991 ret->MEDFileStructuredMesh::operator=(*this);
6992 ret->setMesh(clmesh);
6993 ret->setAxisType(AX_CART);
6998 void MEDFileCMesh::writeMeshLL(med_idt fid) const
7000 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7001 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7002 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7003 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7004 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7005 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7006 int spaceDim(_cmesh->getSpaceDimension());
7007 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7008 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7009 for(int i=0;i<spaceDim;i++)
7011 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
7013 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7014 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
7015 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
7017 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7019 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7020 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
7021 for(int i=0;i<spaceDim;i++)
7023 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
7024 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,ToMedInt(da->getNumberOfTuples()),da->getConstPointer()));
7027 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7028 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7031 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
7033 const MEDCouplingCMesh *cmesh=_cmesh;
7036 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
7037 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
7038 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
7039 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
7042 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
7044 return new MEDFileCurveLinearMesh;
7047 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
7049 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
7052 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
7054 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7055 return New(fid,mrs);
7058 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7060 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7061 return New(fid,mName,dt,it,mrs);
7064 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7066 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
7069 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
7071 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
7074 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
7076 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
7077 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
7081 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
7083 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7087 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
7089 return new MEDFileCurveLinearMesh;
7092 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
7094 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7095 ret->deepCpyEquivalences(*this);
7096 if((const MEDCouplingCurveLinearMesh*)_clmesh)
7097 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
7098 ret->deepCpyAttributes();
7102 int MEDFileCurveLinearMesh::getMeshDimension() const
7104 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7105 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
7106 return _clmesh->getMeshDimension();
7109 std::string MEDFileCurveLinearMesh::simpleRepr() const
7111 return MEDFileStructuredMesh::simpleRepr();
7114 std::string MEDFileCurveLinearMesh::advancedRepr() const
7116 return simpleRepr();
7119 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7121 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7123 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
7126 what="Mesh types differ ! This is curve linear and other is NOT !";
7129 clearNonDiscrAttributes();
7130 otherC->clearNonDiscrAttributes();
7131 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
7132 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
7133 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7135 what="Mismatch of curve linear meshes ! One is defined and not other !";
7140 bool ret=coo1->isEqual(coo2,eps);
7143 what="curve linear meshes differ !";
7150 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
7152 MEDFileStructuredMesh::clearNonDiscrAttributes();
7153 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
7156 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
7158 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
7161 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
7162 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
7163 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
7164 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
7167 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
7169 synchronizeTinyInfoOnLeaves();
7173 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
7175 dealWithTinyInfo(m);
7181 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
7183 if(getAxisType()==AX_CART)
7186 return const_cast<MEDFileCurveLinearMesh *>(this);
7190 const MEDCouplingCurveLinearMesh *mesh(getMesh());
7192 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7193 const DataArrayDouble *coords(mesh->getCoords());
7195 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
7196 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7197 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
7198 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7199 mesh2->setCoords(coordsCart);
7200 ret->setMesh(mesh2);
7201 ret->setAxisType(AX_CART);
7206 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7208 synchronizeTinyInfoOnLeaves();
7212 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7216 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7219 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7221 catch(INTERP_KERNEL::Exception& e)
7226 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7228 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7229 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7230 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7231 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7232 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7233 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7234 int spaceDim=_clmesh->getSpaceDimension();
7235 int meshDim=_clmesh->getMeshDimension();
7236 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7237 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7238 const DataArrayDouble *coords=_clmesh->getCoords();
7240 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7241 for(int i=0;i<spaceDim;i++)
7243 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7245 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7246 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
7247 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
7249 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7251 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7252 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7253 std::vector<mcIdType> nodeGridSt=_clmesh->getNodeGridStructure();
7254 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,ToMedIntArray(nodeGridSt)->getConstPointer()));
7256 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,ToMedInt(coords->getNumberOfTuples()),coords->begin()));
7258 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7259 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7262 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7264 MEDCoupling::MEDCouplingMeshType meshType;
7267 MEDCoupling::MEDCouplingAxisType axType;
7268 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7269 setAxisType(axType);
7270 if(meshType!=CURVE_LINEAR)
7272 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7273 throw INTERP_KERNEL::Exception(oss.str().c_str());
7275 MEDFileCLMeshL2 loaderl2;
7276 loaderl2.loadAll(fid,mid,mName,dt,it);
7277 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7280 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7283 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7285 return new MEDFileMeshMultiTS;
7288 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7290 return new MEDFileMeshMultiTS(fid);
7293 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7295 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7299 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7301 return new MEDFileMeshMultiTS(fid,mName);
7304 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7306 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7307 return New(fid,mName);
7310 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7312 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7313 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7315 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7316 if((const MEDFileMesh *)*it)
7317 meshOneTs[i]=(*it)->deepCopy();
7318 ret->_mesh_one_ts=meshOneTs;
7322 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7324 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7327 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7329 std::vector<const BigMemoryObject *> ret;
7330 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7331 ret.push_back((const MEDFileMesh *)*it);
7335 std::string MEDFileMeshMultiTS::getName() const
7337 if(_mesh_one_ts.empty())
7338 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7339 return _mesh_one_ts[0]->getName();
7342 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7344 std::string oldName(getName());
7345 std::vector< std::pair<std::string,std::string> > v(1);
7346 v[0].first=oldName; v[0].second=newMeshName;
7350 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7353 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7355 MEDFileMesh *cur(*it);
7357 ret=cur->changeNames(modifTab) || ret;
7362 void MEDFileMeshMultiTS::cartesianizeMe()
7364 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7366 MEDFileMesh *cur(*it);
7369 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7375 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7377 if(_mesh_one_ts.empty())
7378 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7379 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7382 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7385 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7386 _mesh_one_ts.resize(1);
7387 mesh1TimeStep->incrRef();
7388 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7389 _mesh_one_ts[0]=mesh1TimeStep;
7392 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7394 if ( MEDFileMesh* m = getOneTimeStep() )
7395 return m->getJoints();
7400 * \brief Set Joints that are common to all time-stamps
7402 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7404 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7406 (*it)->setJoints( joints );
7410 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7412 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7413 if((*it).isNotNull())
7414 if((*it)->presenceOfStructureElements())
7419 void MEDFileMeshMultiTS::killStructureElements()
7421 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7422 if((*it).isNotNull())
7423 (*it)->killStructureElements();
7426 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7428 MEDFileJoints *joints(getJoints());
7429 bool jointsWritten(false);
7431 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7433 if ( jointsWritten )
7434 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7436 jointsWritten = true;
7438 (*it)->copyOptionsFrom(*this);
7439 (*it)->writeLL(fid);
7442 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7445 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7447 MEDFileJoints *joints(0);
7448 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7450 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7451 joints = getOneTimeStep()->getJoints();
7453 _mesh_one_ts.clear(); //for the moment to be improved
7454 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7457 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7461 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7464 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7467 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7468 throw INTERP_KERNEL::Exception(oss.str().c_str());
7471 MEDCoupling::MEDCouplingMeshType meshType;
7473 MEDCoupling::MEDCouplingAxisType dummy3;
7474 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7475 loadFromFile(fid,ms.front());
7477 catch(INTERP_KERNEL::Exception& e)
7482 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7485 loadFromFile(fid,mName);
7487 catch(INTERP_KERNEL::Exception& e)
7492 MEDFileMeshes *MEDFileMeshes::New()
7494 return new MEDFileMeshes;
7497 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7499 return new MEDFileMeshes(fid);
7502 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7504 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7508 void MEDFileMeshes::writeLL(med_idt fid) const
7510 checkConsistencyLight();
7511 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7513 (*it)->copyOptionsFrom(*this);
7514 (*it)->writeLL(fid);
7518 // MEDFileMeshes::writ checkConsistencyLight();
7520 int MEDFileMeshes::getNumberOfMeshes() const
7522 return (int)_meshes.size();
7525 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7527 return new MEDFileMeshesIterator(this);
7530 /** Return a borrowed reference (caller is not responsible) */
7531 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7533 if(i<0 || i>=(int)_meshes.size())
7535 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7536 throw INTERP_KERNEL::Exception(oss.str().c_str());
7538 return _meshes[i]->getOneTimeStep();
7541 /** Return a borrowed reference (caller is not responsible) */
7542 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7544 std::vector<std::string> ms=getMeshesNames();
7545 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7548 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7549 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7550 throw INTERP_KERNEL::Exception(oss.str().c_str());
7552 return getMeshAtPos((int)std::distance(ms.begin(),it));
7555 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7557 std::vector<std::string> ret(_meshes.size());
7559 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7561 const MEDFileMeshMultiTS *f=(*it);
7564 ret[i]=f->getName();
7568 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7569 throw INTERP_KERNEL::Exception(oss.str().c_str());
7575 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7578 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7580 MEDFileMeshMultiTS *cur(*it);
7582 ret=cur->changeNames(modifTab) || ret;
7587 void MEDFileMeshes::cartesianizeMe()
7589 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7591 MEDFileMeshMultiTS *cur(*it);
7593 cur->cartesianizeMe();
7597 void MEDFileMeshes::resize(int newSize)
7599 _meshes.resize(newSize);
7602 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7605 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7606 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7607 elt->setOneTimeStep(mesh);
7608 _meshes.push_back(elt);
7611 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7614 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7615 if(i>=(int)_meshes.size())
7616 _meshes.resize(i+1);
7617 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7618 elt->setOneTimeStep(mesh);
7622 void MEDFileMeshes::destroyMeshAtPos(int i)
7624 if(i<0 || i>=(int)_meshes.size())
7626 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7627 throw INTERP_KERNEL::Exception(oss.str().c_str());
7629 _meshes.erase(_meshes.begin()+i);
7632 void MEDFileMeshes::loadFromFile(med_idt fid)
7634 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7636 _meshes.resize(ms.size());
7637 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7638 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7641 MEDFileMeshes::MEDFileMeshes()
7645 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7650 catch(INTERP_KERNEL::Exception& /*e*/)
7654 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7656 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7658 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7659 if((const MEDFileMeshMultiTS *)*it)
7660 meshes[i]=(*it)->deepCopy();
7661 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7662 ret->_meshes=meshes;
7666 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7668 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7671 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7673 std::vector<const BigMemoryObject *> ret;
7674 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7675 ret.push_back((const MEDFileMeshMultiTS *)*it);
7679 std::string MEDFileMeshes::simpleRepr() const
7681 std::ostringstream oss;
7682 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7683 simpleReprWithoutHeader(oss);
7687 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7689 int nbOfMeshes=getNumberOfMeshes();
7690 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7691 std::vector<std::string> mns=getMeshesNames();
7692 for(int i=0;i<nbOfMeshes;i++)
7693 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7696 void MEDFileMeshes::checkConsistencyLight() const
7698 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7700 std::set<std::string> s;
7701 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7703 const MEDFileMeshMultiTS *elt=(*it);
7706 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7707 throw INTERP_KERNEL::Exception(oss.str().c_str());
7709 std::size_t sz=s.size();
7710 s.insert(std::string((*it)->getName()));
7713 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7714 throw INTERP_KERNEL::Exception(oss.str().c_str());
7719 bool MEDFileMeshes::presenceOfStructureElements() const
7721 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7722 if((*it).isNotNull())
7723 if((*it)->presenceOfStructureElements())
7728 void MEDFileMeshes::killStructureElements()
7730 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7731 if((*it).isNotNull())
7732 (*it)->killStructureElements();
7735 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7740 _nb_iter=ms->getNumberOfMeshes();
7744 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7748 MEDFileMesh *MEDFileMeshesIterator::nextt()
7750 if(_iter_id<_nb_iter)
7752 MEDFileMeshes *ms(_ms);
7754 return ms->getMeshAtPos(_iter_id++);
7762 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7764 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7765 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7767 if(geoType==MED_NO_GEOTYPE)
7768 return INTERP_KERNEL::NORM_ERROR;
7769 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7770 throw INTERP_KERNEL::Exception(oss.str());
7772 return typmai2[std::distance(typmai,pos)];
7775 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7783 case MED_NODE_ELEMENT:
7787 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7788 throw INTERP_KERNEL::Exception(oss.str());