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 void MEDFileUMesh::LoadPartCoords(const std::string& fileName, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, mcIdType nMin, mcIdType nMax,
2482 MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<DataArrayIdType>& famCoords, MCAuto<DataArrayIdType>& numCoords, MCAuto<DataArrayAsciiChar>& nameCoords)
2484 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2485 MEDFileUMeshL2::LoadPartCoords(fid,infosOnComp,mName,dt,it,nMin,nMax,coords,partCoords,famCoords,numCoords,nameCoords);
2488 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2490 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2491 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2495 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2497 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2498 ret.push_back((const DataArrayDouble*)_coords);
2499 ret.push_back((const DataArrayIdType *)_fam_coords);
2500 ret.push_back((const DataArrayIdType *)_num_coords);
2501 ret.push_back((const DataArrayIdType *)_global_num_coords);
2502 ret.push_back((const DataArrayIdType *)_rev_num_coords);
2503 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2504 ret.push_back((const PartDefinition *)_part_coords);
2505 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2506 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2507 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2508 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2512 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2514 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2518 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2520 return new MEDFileUMesh;
2523 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2525 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2526 ret->deepCpyEquivalences(*this);
2527 if(_coords.isNotNull())
2528 ret->_coords=_coords->deepCopy();
2529 if(_fam_coords.isNotNull())
2530 ret->_fam_coords=_fam_coords->deepCopy();
2531 if(_num_coords.isNotNull())
2532 ret->_num_coords=_num_coords->deepCopy();
2533 if(_global_num_coords.isNotNull())
2534 ret->_global_num_coords=_global_num_coords->deepCopy();
2535 if(_rev_num_coords.isNotNull())
2536 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2537 if(_name_coords.isNotNull())
2538 ret->_name_coords=_name_coords->deepCopy();
2540 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2542 if((const MEDFileUMeshSplitL1 *)(*it))
2543 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2545 if((const PartDefinition*)_part_coords)
2546 ret->_part_coords=_part_coords->deepCopy();
2551 * Checks if \a this and another mesh are equal.
2552 * \param [in] other - the mesh to compare with.
2553 * \param [in] eps - a precision used to compare real values.
2554 * \param [in,out] what - the string returning description of unequal data.
2555 * \return bool - \c true if the meshes are equal, \c false, else.
2557 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2559 if(!MEDFileMesh::isEqual(other,eps,what))
2561 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2564 what="Mesh types differ ! This is unstructured and other is NOT !";
2567 clearNonDiscrAttributes();
2568 otherC->clearNonDiscrAttributes();
2569 const DataArrayDouble *coo1=_coords;
2570 const DataArrayDouble *coo2=otherC->_coords;
2571 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2573 what="Mismatch of coordinates ! One is defined and not other !";
2578 bool ret=coo1->isEqual(*coo2,eps);
2581 what="Coords differ !";
2586 const DataArrayIdType *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2587 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2589 what="Mismatch of families arr on nodes ! One is defined and not other !";
2594 bool ret=famc1->isEqual(*famc2);
2597 what="Families arr on node differ !";
2603 const DataArrayIdType *numc1(_num_coords),*numc2(otherC->_num_coords);
2604 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2606 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2611 bool ret=numc1->isEqual(*numc2);
2614 what="Numbering arr on node differ !";
2620 const DataArrayIdType *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2621 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2623 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2628 bool ret=gnumc1->isEqual(*gnumc2);
2631 what="Global numbering arr on node differ !";
2637 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2638 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2640 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2645 bool ret=namec1->isEqual(*namec2);
2648 what="Names arr on node differ !";
2653 if(_ms.size()!=otherC->_ms.size())
2655 what="Number of levels differs !";
2658 std::size_t sz=_ms.size();
2659 for(std::size_t i=0;i<sz;i++)
2661 const MEDFileUMeshSplitL1 *s1=_ms[i];
2662 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2663 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2665 what="Mismatch of presence of sub levels !";
2670 bool ret=s1->isEqual(s2,eps,what);
2675 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2678 if((!pd0 && pd1) || (pd0 && !pd1))
2680 what=std::string("node part def is defined only for one among this or other !");
2683 return pd0->isEqual(pd1,what);
2687 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2688 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2689 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2690 * \throw if internal family array is inconsistent
2691 * \sa checkSMESHConsistency()
2693 void MEDFileUMesh::checkConsistency() const
2695 if(!_coords || !_coords->isAllocated())
2698 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2700 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2701 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2702 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2706 mcIdType nbCoo = _coords->getNumberOfTuples();
2707 if (_fam_coords.isNotNull())
2708 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2709 if (_num_coords.isNotNull())
2711 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2713 mcIdType maxValue=_num_coords->getMaxValue(pos);
2714 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2715 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2717 if (_global_num_coords.isNotNull())
2719 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2721 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2722 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2723 if (_num_coords && !_num_coords->hasUniqueValues())
2724 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2726 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2727 // Now sub part check:
2728 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2729 it != _ms.end(); it++)
2730 (*it)->checkConsistency();
2735 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2736 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2737 * entities as it likes), or non overlapping between all sub-levels.
2738 * \throw if the condition above is not respected
2740 void MEDFileUMesh::checkSMESHConsistency() const
2743 // For all sub-levels, numbering is either always null or with void intersection:
2746 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2747 std::vector< const DataArrayIdType * > v;
2748 bool voidOrNot = ((*it)->_num == 0);
2749 for (it++; it != _ms.end(); it++)
2750 if( ((*it)->_num == 0) != voidOrNot )
2751 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2752 else if (!voidOrNot)
2753 v.push_back((*it)->_num);
2756 // don't forget the 1st one:
2757 v.push_back(_ms[0]->_num);
2758 MCAuto<DataArrayIdType> inter = DataArrayIdType::BuildIntersection(v);
2759 if (inter->getNumberOfTuples())
2760 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2766 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2767 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2769 void MEDFileUMesh::clearNodeAndCellNumbers()
2771 _num_coords.nullify();
2772 _rev_num_coords.nullify();
2773 _global_num_coords.nullify();
2774 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2776 (*it)->_num.nullify();
2777 (*it)->_rev_num.nullify();
2778 (*it)->_global_num.nullify();
2783 * Clears redundant attributes of incorporated data arrays.
2785 void MEDFileUMesh::clearNonDiscrAttributes() const
2787 MEDFileMesh::clearNonDiscrAttributes();
2788 if(_coords.isNotNull())
2789 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2790 if(_fam_coords.isNotNull())
2791 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2792 if(_num_coords.isNotNull())
2793 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2794 if(_name_coords.isNotNull())
2795 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2796 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2798 if((*it).isNotNull())
2799 (*it)->clearNonDiscrAttributes();
2803 void MEDFileUMesh::setName(const std::string& name)
2805 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2806 if((*it).isNotNull())
2807 (*it)->setName(name);
2808 MEDFileMesh::setName(name);
2811 MEDFileUMesh::MEDFileUMesh()
2815 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2818 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2820 catch(INTERP_KERNEL::Exception& e)
2826 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2827 * See MEDFileUMesh::LoadPartOf for detailed description.
2831 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)
2833 MEDFileUMeshL2 loaderl2;
2834 MEDCoupling::MEDCouplingMeshType meshType;
2837 MEDCoupling::MEDCouplingAxisType dummy3;
2838 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2839 if(meshType!=UNSTRUCTURED)
2841 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2842 throw INTERP_KERNEL::Exception(oss.str().c_str());
2844 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2845 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2849 * \brief Write joints in a file
2851 void MEDFileMesh::writeJoints(med_idt fid) const
2853 if ( _joints.isNotNull() )
2854 _joints->writeLL(fid);
2858 * \brief Load joints in a file or use provided ones
2860 //================================================================================
2862 * \brief Load joints in a file or use provided ones
2863 * \param [in] fid - MED file descriptor
2864 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2865 * Usually this joints are those just read by another iteration
2866 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2868 //================================================================================
2870 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2872 if ( toUseInstedOfReading )
2873 setJoints( toUseInstedOfReading );
2875 _joints = MEDFileJoints::New( fid, _name );
2878 void MEDFileMesh::loadEquivalences(med_idt fid)
2880 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2882 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2885 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2887 const MEDFileEquivalences *equiv(other._equiv);
2889 _equiv=equiv->deepCopy(this);
2892 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2894 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2895 if(!thisEq && !otherEq)
2897 if(thisEq && otherEq)
2898 return thisEq->isEqual(otherEq,what);
2901 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2906 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2908 const MEDFileEquivalences *equiv(_equiv);
2911 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2912 _equiv->getRepr(oss);
2915 void MEDFileMesh::checkCartesian() const
2917 if(getAxisType()!=AX_CART)
2919 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()) << ").";
2920 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2921 oss << " - call setAxisType(AX_CART)" << std::endl;
2922 oss << " - call cartesianize()";
2923 throw INTERP_KERNEL::Exception(oss.str().c_str());
2928 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2930 int MEDFileMesh::getNumberOfJoints() const
2932 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2936 * \brief Return joints with all adjacent mesh domains
2938 MEDFileJoints * MEDFileMesh::getJoints() const
2940 return const_cast<MEDFileJoints*>(& (*_joints));
2943 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2945 if ( joints != _joints )
2954 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2956 * \sa loadPartUMeshFromFile
2958 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2960 MEDFileUMeshL2 loaderl2;
2961 MEDCoupling::MEDCouplingMeshType meshType;
2964 MEDCoupling::MEDCouplingAxisType axType;
2965 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2966 setAxisType(axType);
2967 if(meshType!=UNSTRUCTURED)
2969 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2970 throw INTERP_KERNEL::Exception(oss.str().c_str());
2972 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2973 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2974 // Structure element part...
2975 med_int nModels(-1);
2977 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2978 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2982 _elt_str.resize(nModels);
2983 for(int i=0;i<nModels;i++)
2984 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2987 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2989 int lev=loaderl2.getNumberOfLevels();
2991 for(int i=0;i<lev;i++)
2993 if(!loaderl2.emptyLev(i))
2994 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2998 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
3000 setName(loaderl2.getName());
3001 setDescription(loaderl2.getDescription());
3002 setUnivName(loaderl2.getUnivName());
3003 setIteration(loaderl2.getIteration());
3004 setOrder(loaderl2.getOrder());
3005 setTimeValue(loaderl2.getTime());
3006 setTimeUnit(loaderl2.getTimeUnit());
3007 _coords=loaderl2.getCoords();
3008 if(!mrs || mrs->isNodeFamilyFieldReading())
3009 _fam_coords=loaderl2.getCoordsFamily();
3010 if(!mrs || mrs->isNodeNumFieldReading())
3011 _num_coords=loaderl2.getCoordsNum();
3012 if(!mrs || mrs->isNodeNameFieldReading())
3013 _name_coords=loaderl2.getCoordsName();
3014 if(!mrs || mrs->isGlobalNodeNumFieldReading())
3015 _global_num_coords=loaderl2.getCoordsGlobalNum();
3016 _part_coords=loaderl2.getPartDefOfCoo();
3020 MEDFileUMesh::~MEDFileUMesh()
3024 void MEDFileUMesh::writeMeshLL(med_idt fid) const
3026 const DataArrayDouble *coo=_coords;
3027 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3028 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3029 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3030 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3031 int spaceDim=(int)(coo?coo->getNumberOfComponents():0);
3034 mdim=getMeshDimension();
3035 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3036 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3037 for(int i=0;i<spaceDim;i++)
3039 std::string info=coo->getInfoOnComponent(i);
3041 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3042 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
3043 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
3045 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
3047 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
3048 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
3049 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
3050 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3051 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3052 (*it)->write(fid,meshName,mdim);
3053 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
3057 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
3058 * \return std::vector<int> - a sequence of the relative dimensions.
3060 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
3062 std::vector<int> ret;
3064 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3065 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3072 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
3073 * \return std::vector<int> - a sequence of the relative dimensions.
3075 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
3077 std::vector<int> ret0=getNonEmptyLevels();
3078 if((const DataArrayDouble *) _coords)
3080 std::vector<int> ret(ret0.size()+1);
3082 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3088 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
3090 std::vector<int> ret;
3091 const DataArrayIdType *famCoo(_fam_coords);
3095 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3097 const MEDFileUMeshSplitL1 *cur(*it);
3099 if(cur->getFamilyField())
3105 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3107 std::vector<int> ret;
3108 if(_num_coords.isNotNull())
3111 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3113 const MEDFileUMeshSplitL1 *cur(*it);
3115 if(cur->getNumberField())
3121 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3123 std::vector<int> ret;
3124 const DataArrayAsciiChar *nameCoo(_name_coords);
3128 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3130 const MEDFileUMeshSplitL1 *cur(*it);
3132 if(cur->getNameField())
3139 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3140 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3141 * \param [in] fams - the name of the family of interest.
3142 * \return std::vector<int> - a sequence of the relative dimensions.
3144 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3146 std::vector<mcIdType> ret;
3147 std::vector<int> levs(getNonEmptyLevels());
3148 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3149 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3150 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3156 * Returns all relative mesh levels (including nodes) where given families are defined.
3157 * \param [in] fams - the names of the families of interest.
3158 * \return std::vector<int> - a sequence of the relative dimensions.
3160 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3162 std::vector<mcIdType> ret0(getFamsNonEmptyLevels(fams));
3163 const DataArrayIdType *famCoords(_fam_coords);
3166 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3167 if(famCoords->presenceOfValue(famIds))
3169 std::vector<mcIdType> ret(ret0.size()+1);
3171 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3178 mcIdType MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3180 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3181 if((const DataArrayIdType *)_fam_coords)
3183 mcIdType val=_fam_coords->getMaxValue(tmp);
3184 ret=std::max(ret,std::abs(val));
3186 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3188 if((const MEDFileUMeshSplitL1 *)(*it))
3190 const DataArrayIdType *da=(*it)->getFamilyField();
3193 mcIdType val=da->getMaxValue(tmp);
3194 ret=std::max(ret,std::abs(val));
3201 mcIdType MEDFileUMesh::getMaxFamilyIdInArrays() const
3203 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3204 if((const DataArrayIdType *)_fam_coords)
3206 mcIdType val=_fam_coords->getMaxValue(tmp);
3207 ret=std::max(ret,val);
3209 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3211 if((const MEDFileUMeshSplitL1 *)(*it))
3213 const DataArrayIdType *da=(*it)->getFamilyField();
3216 mcIdType val=da->getMaxValue(tmp);
3217 ret=std::max(ret,val);
3224 mcIdType MEDFileUMesh::getMinFamilyIdInArrays() const
3226 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
3227 if((const DataArrayIdType *)_fam_coords)
3229 mcIdType val=_fam_coords->getMinValue(tmp);
3230 ret=std::min(ret,val);
3232 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3234 if((const MEDFileUMeshSplitL1 *)(*it))
3236 const DataArrayIdType *da=(*it)->getFamilyField();
3239 mcIdType val=da->getMinValue(tmp);
3240 ret=std::min(ret,val);
3248 * Returns the dimension on cells in \a this mesh.
3249 * \return int - the mesh dimension.
3250 * \throw If there are no cells in this mesh.
3252 int MEDFileUMesh::getMeshDimension() const
3255 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3256 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3257 return (*it)->getMeshDimension()+lev;
3258 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3262 * Returns the space dimension of \a this mesh that is equal to number of components in
3263 * the node coordinates array.
3264 * \return int - the space dimension of \a this mesh.
3265 * \throw If the node coordinates array is not available.
3267 int MEDFileUMesh::getSpaceDimension() const
3269 const DataArrayDouble *coo=_coords;
3271 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3272 return (int)coo->getNumberOfComponents();
3276 * Returns a string describing \a this mesh.
3277 * \return std::string - the mesh information string.
3279 std::string MEDFileUMesh::simpleRepr() const
3281 std::ostringstream oss;
3282 oss << MEDFileMesh::simpleRepr();
3283 const DataArrayDouble *coo=_coords;
3284 oss << "- The dimension of the space is ";
3285 static const char MSG1[]= "*** NO COORDS SET ***";
3286 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3288 oss << _coords->getNumberOfComponents() << std::endl;
3290 oss << MSG1 << std::endl;
3291 oss << "- Type of the mesh : UNSTRUCTURED\n";
3292 oss << "- Number of nodes : ";
3294 oss << _coords->getNumberOfTuples() << std::endl;
3296 oss << MSG1 << std::endl;
3297 std::size_t nbOfLev=_ms.size();
3298 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3299 for(std::size_t i=0;i<nbOfLev;i++)
3301 const MEDFileUMeshSplitL1 *lev=_ms[i];
3302 oss << " - Level #" << -((int) i) << " has dimension : ";
3305 oss << lev->getMeshDimension() << std::endl;
3306 lev->simpleRepr(oss);
3309 oss << MSG2 << std::endl;
3311 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3314 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3315 oss << "- Names of coordinates :" << std::endl;
3316 std::vector<std::string> vars=coo->getVarsOnComponent();
3317 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3318 oss << std::endl << "- Units of coordinates : " << std::endl;
3319 std::vector<std::string> units=coo->getUnitsOnComponent();
3320 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3322 oss << std::endl << std::endl;
3324 getEquivalencesRepr(oss);
3329 * Returns a full textual description of \a this mesh.
3330 * \return std::string - the string holding the mesh description.
3332 std::string MEDFileUMesh::advancedRepr() const
3334 return simpleRepr();
3338 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3339 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3340 * \return mcIdType - the number of entities.
3341 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3343 mcIdType MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3345 if(meshDimRelToMaxExt==1)
3347 if(!((const DataArrayDouble *)_coords))
3348 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3349 return _coords->getNumberOfTuples();
3351 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3355 * Returns the family field for mesh entities of a given dimension.
3356 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3357 * \return const DataArrayIdType * - the family field. It is an array of ids of families
3358 * each mesh entity belongs to. It can be \c NULL.
3360 const DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3362 if(meshDimRelToMaxExt==1)
3364 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3365 return l1->getFamilyField();
3368 DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3370 if(meshDimRelToMaxExt==1)
3372 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3373 return l1->getFamilyField();
3377 * Returns the optional numbers of mesh entities of a given dimension.
3378 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3379 * \return const DataArrayIdType * - the array of the entity numbers.
3380 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3382 const DataArrayIdType *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3384 if(meshDimRelToMaxExt==1)
3386 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3387 return l1->getNumberField();
3390 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3392 if(meshDimRelToMaxExt==1)
3393 return _name_coords;
3394 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3395 return l1->getNameField();
3398 MCAuto<DataArrayIdType> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3400 if(meshDimRelToMaxExt!=1)
3401 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3402 return _global_num_coords;
3406 * 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).
3408 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3409 * \param [in] gt - The input geometric type for which the part definition is requested.
3410 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3412 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3414 if(meshDimRelToMaxExt==1)
3415 return _part_coords;
3416 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3417 return l1->getPartDef(gt);
3420 mcIdType MEDFileUMesh::getNumberOfNodes() const
3422 const DataArrayDouble *coo(_coords);
3424 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3425 return coo->getNumberOfTuples();
3428 mcIdType MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3430 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3431 return l1->getNumberOfCells();
3434 bool MEDFileUMesh::hasImplicitPart() const
3439 mcIdType MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3441 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3444 void MEDFileUMesh::releaseImplicitPartIfAny() const
3448 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3450 std::size_t sz(st.getNumberOfItems());
3451 for(std::size_t i=0;i<sz;i++)
3453 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3454 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3455 if(st[i].getPflName().empty())
3456 m->computeNodeIdsAlg(nodesFetched);
3459 const DataArrayIdType *arr(globs->getProfile(st[i].getPflName()));
3460 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3461 m2->computeNodeIdsAlg(nodesFetched);
3466 MEDFileMesh *MEDFileUMesh::cartesianize() const
3468 if(getAxisType()==AX_CART)
3471 return const_cast<MEDFileUMesh *>(this);
3475 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3476 const DataArrayDouble *coords(_coords);
3478 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3479 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3480 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3481 if((const MEDFileUMeshSplitL1 *)(*it))
3482 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3483 ret->_coords=coordsCart;
3484 ret->setAxisType(AX_CART);
3489 bool MEDFileUMesh::presenceOfStructureElements() const
3491 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3492 if((*it).isNotNull())
3497 void MEDFileUMesh::killStructureElements()
3503 * Returns the optional numbers of mesh entities of a given dimension transformed using
3504 * DataArrayIdType::invertArrayN2O2O2N().
3505 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3506 * \return const DataArrayIdType * - the array of the entity numbers transformed using
3507 * DataArrayIdType::invertArrayN2O2O2N().
3508 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3510 const DataArrayIdType *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3512 if(meshDimRelToMaxExt==1)
3514 if(_num_coords.isNull())
3515 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3516 return _rev_num_coords;
3518 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3519 return l1->getRevNumberField();
3523 * Returns a pointer to the node coordinates array of \a this mesh \b without
3524 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3526 DataArrayDouble *MEDFileUMesh::getCoords() const
3529 MCAuto<DataArrayDouble> tmp(_coords);
3530 if((DataArrayDouble *)tmp)
3538 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3539 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3541 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3542 * \param [in] grp - the name of the group whose mesh entities are included in the
3544 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3545 * according to the optional numbers of entities, if available.
3546 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3547 * delete this mesh using decrRef() as it is no more needed.
3548 * \throw If the name of a nonexistent group is specified.
3549 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3551 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3554 synchronizeTinyInfoOnLeaves();
3555 std::vector<std::string> tmp(1);
3557 return getGroups(meshDimRelToMaxExt,tmp,renum);
3561 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3562 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3564 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3565 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3567 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3568 * according to the optional numbers of entities, if available.
3569 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3570 * delete this mesh using decrRef() as it is no more needed.
3571 * \throw If a name of a nonexistent group is present in \a grps.
3572 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3574 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3577 synchronizeTinyInfoOnLeaves();
3578 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3579 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3580 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3581 zeRet->setName(grps[0]);
3582 return zeRet.retn();
3586 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3587 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3589 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3590 * \param [in] fam - the name of the family whose mesh entities are included in the
3592 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3593 * according to the optional numbers of entities, if available.
3594 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3595 * delete this mesh using decrRef() as it is no more needed.
3596 * \throw If a name of a nonexistent family is present in \a grps.
3597 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3599 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3602 synchronizeTinyInfoOnLeaves();
3603 std::vector<std::string> tmp(1);
3605 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3609 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3610 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3612 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3613 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3615 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3616 * according to the optional numbers of entities, if available.
3617 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3618 * delete this mesh using decrRef() as it is no more needed.
3619 * \throw If a name of a nonexistent family is present in \a fams.
3620 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3622 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3625 synchronizeTinyInfoOnLeaves();
3626 if(meshDimRelToMaxExt==1)
3628 MCAuto<DataArrayIdType> arr=getFamiliesArr(1,fams,renum);
3629 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3630 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3634 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3635 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3636 MCAuto<MEDCouplingUMesh> zeRet;
3638 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3640 zeRet=l1->getFamilyPart(0,0,renum);
3641 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3642 zeRet->setName(fams[0]);
3643 return zeRet.retn();
3647 * Returns ids of mesh entities contained in given families of a given dimension.
3648 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3650 * \param [in] fams - the names of the families of interest.
3651 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3652 * returned instead of ids.
3653 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
3654 * numbers, if available and required, of mesh entities of the families. The caller
3655 * is to delete this array using decrRef() as it is no more needed.
3656 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3658 DataArrayIdType *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3660 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3661 if(meshDimRelToMaxExt==1)
3663 if((const DataArrayIdType *)_fam_coords)
3665 MCAuto<DataArrayIdType> da;
3667 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3669 da=_fam_coords->findIdsEqualList(0,0);
3671 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3676 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3678 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3680 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3682 return l1->getFamilyPartArr(0,0,renum);
3686 * Returns a MEDCouplingUMesh of a given relative dimension.
3687 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3688 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3689 * To build a valid MEDCouplingUMesh from the returned one in this case,
3690 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3691 * \param [in] meshDimRelToMax - the relative dimension of interest.
3692 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3693 * optional numbers of mesh entities.
3694 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3695 * delete using decrRef() as it is no more needed.
3696 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3698 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3701 synchronizeTinyInfoOnLeaves();
3702 if(meshDimRelToMaxExt==1)
3706 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3707 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3708 umesh->setCoords(cc);
3709 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3710 umesh->setName(getName());
3714 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3715 return l1->getWholeMesh(renum);
3718 std::vector<mcIdType> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3720 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3721 return l1->getDistributionOfTypes();
3725 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3726 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3727 * optional numbers of mesh entities.
3728 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3729 * delete using decrRef() as it is no more needed.
3730 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3732 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3734 return getMeshAtLevel(0,renum);
3738 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3739 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3740 * optional numbers of mesh entities.
3741 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3742 * delete using decrRef() as it is no more needed.
3743 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3745 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3747 return getMeshAtLevel(-1,renum);
3751 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3752 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3753 * optional numbers of mesh entities.
3754 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3755 * delete using decrRef() as it is no more needed.
3756 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3758 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3760 return getMeshAtLevel(-2,renum);
3764 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3765 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3766 * optional numbers of mesh entities.
3767 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3768 * delete using decrRef() as it is no more needed.
3769 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3771 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3773 return getMeshAtLevel(-3,renum);
3777 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3778 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3779 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3780 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3782 void MEDFileUMesh::forceComputationOfParts() const
3784 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3786 const MEDFileUMeshSplitL1 *elt(*it);
3788 elt->forceComputationOfParts();
3793 * This method returns a vector of mesh parts containing each exactly one geometric type.
3794 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3795 * This method is only for memory aware users.
3796 * The returned pointers are **NOT** new object pointer. No need to mange them.
3798 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3801 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3802 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3806 * This method returns the part of \a this having the geometric type \a gt.
3807 * If such part is not existing an exception will be thrown.
3808 * The returned pointer is **NOT** new object pointer. No need to mange it.
3810 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3813 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3814 int lev=(int)cm.getDimension()-getMeshDimension();
3815 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3816 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3820 * This method returns for each geo types in \a this number of cells with this geo type.
3821 * 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.
3822 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3824 * \sa getDistributionOfTypes
3826 std::vector< std::pair<int,mcIdType> > MEDFileUMesh::getAllDistributionOfTypes() const
3828 std::vector< std::pair<int,mcIdType> > ret;
3829 std::vector<int> nel(getNonEmptyLevels());
3830 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3832 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3833 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3835 mcIdType nbCells(getNumberOfCellsWithType(*it1));
3836 ret.push_back(std::pair<int,mcIdType>(*it1,nbCells));
3839 ret.push_back(std::pair<int,mcIdType>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3844 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3845 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3847 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3849 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3850 return sp->getGeoTypes();
3853 mcIdType MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3855 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3856 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3857 return sp->getNumberOfCellsWithType(ct);
3861 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3862 * \param [in] gt - the geometric type for which the family field is asked.
3863 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
3864 * delete using decrRef() as it is no more needed.
3865 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3867 DataArrayIdType *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3869 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3870 int lev=(int)cm.getDimension()-getMeshDimension();
3871 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3872 return sp->extractFamilyFieldOnGeoType(gt);
3876 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3877 * \param [in] gt - the geometric type for which the number field is asked.
3878 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
3879 * delete using decrRef() as it is no more needed.
3880 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3882 DataArrayIdType *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3884 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3885 int lev=(int)cm.getDimension()-getMeshDimension();
3886 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3887 return sp->extractNumberFieldOnGeoType(gt);
3891 * This method returns for specified geometric type \a gt the relative level to \a this.
3892 * If the relative level is empty an exception will be thrown.
3894 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3896 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3897 int ret((int)cm.getDimension()-getMeshDimension());
3898 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3902 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3904 if(meshDimRelToMaxExt==1)
3905 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3906 if(meshDimRelToMaxExt>1)
3907 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3908 int tracucedRk=-meshDimRelToMaxExt;
3909 if(tracucedRk>=(int)_ms.size())
3910 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3911 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3912 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3913 return _ms[tracucedRk];
3916 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3918 if(meshDimRelToMaxExt==1)
3919 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3920 if(meshDimRelToMaxExt>1)
3921 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3922 int tracucedRk=-meshDimRelToMaxExt;
3923 if(tracucedRk>=(int)_ms.size())
3924 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3925 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3926 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3927 return _ms[tracucedRk];
3930 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3932 if(-meshDimRelToMax>=(int)_ms.size())
3933 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3935 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3937 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3939 int ref=(*it)->getMeshDimension();
3940 if(ref+i!=meshDim-meshDimRelToMax)
3941 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3947 * Sets the node coordinates array of \a this mesh.
3948 * \param [in] coords - the new node coordinates array.
3949 * \throw If \a coords == \c NULL.
3951 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3954 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3955 if(coords==(DataArrayDouble *)_coords)
3957 coords->checkAllocated();
3958 mcIdType nbOfTuples(coords->getNumberOfTuples());
3959 _coords.takeRef(coords);
3960 _fam_coords=DataArrayIdType::New();
3961 _fam_coords->alloc(nbOfTuples,1);
3962 _fam_coords->fillWithZero();
3963 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3964 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3965 if((MEDFileUMeshSplitL1 *)(*it))
3966 (*it)->setCoords(coords);
3970 * Change coords without changing anything concerning families and numbering on nodes.
3972 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3975 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3976 if(coords==(DataArrayDouble *)_coords)
3978 coords->checkAllocated();
3979 mcIdType nbOfTuples(coords->getNumberOfTuples());
3980 if(_coords.isNull())
3987 mcIdType oldNbTuples(_coords->getNumberOfTuples());
3988 if(oldNbTuples!=nbOfTuples)
3989 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3993 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3994 if((MEDFileUMeshSplitL1 *)(*it))
3995 (*it)->setCoords(coords);
3999 * Removes all groups of a given dimension in \a this mesh.
4000 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4001 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4003 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
4005 if(meshDimRelToMaxExt==1)
4007 if((DataArrayIdType *)_fam_coords)
4008 _fam_coords->fillWithZero();
4011 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
4012 l1->eraseFamilyField();
4017 * Removes all families with ids not present in the family fields of \a this mesh.
4019 void MEDFileUMesh::optimizeFamilies()
4021 std::vector<int> levs=getNonEmptyLevelsExt();
4022 std::set<mcIdType> allFamsIds;
4023 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4025 const DataArrayIdType *ffield=getFamilyFieldAtLevel(*it);
4026 MCAuto<DataArrayIdType> ids=ffield->getDifferentValues();
4027 std::set<mcIdType> res;
4028 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
4031 std::set<std::string> famNamesToKill;
4032 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
4034 if(allFamsIds.find((*it).second)!=allFamsIds.end())
4035 famNamesToKill.insert((*it).first);
4037 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
4038 _families.erase(*it);
4039 std::vector<std::string> grpNamesToKill;
4040 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
4042 std::vector<std::string> tmp;
4043 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
4045 if(famNamesToKill.find(*it2)==famNamesToKill.end())
4046 tmp.push_back(*it2);
4051 tmp.push_back((*it).first);
4053 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
4058 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
4059 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
4060 * The boundary is built according to the following method:
4061 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
4062 * coordinates array is extended).
4063 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
4064 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
4065 * might not be duplicated at all.
4066 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
4067 * other side of the group is no more a neighbor)
4068 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
4069 * bordering the newly created boundary use the newly computed nodes.
4070 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
4071 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
4073 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
4074 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
4076 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
4077 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
4078 * \sa clearNodeAndCellNumbers()
4080 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayIdType *&nodesDuplicated,
4081 DataArrayIdType *&cellsModified, DataArrayIdType *&cellsNotModified)
4083 typedef MCAuto<MEDCouplingUMesh> MUMesh;
4084 typedef MCAuto<DataArrayIdType> DAInt;
4086 std::vector<int> levs=getNonEmptyLevels();
4087 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
4088 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
4089 MUMesh m0=getMeshAtLevel(0);
4090 MUMesh m1=getMeshAtLevel(-1);
4091 mcIdType nbNodes=m0->getNumberOfNodes();
4092 MUMesh m11=getGroup(-1,grpNameM1);
4093 DataArrayIdType *tmp00=0,*tmp11=0,*tmp22=0;
4094 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
4095 DAInt nodeIdsToDuplicate(tmp00);
4096 DAInt cellsToModifyConn0(tmp11);
4097 DAInt cellsToModifyConn1(tmp22);
4098 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4099 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4100 DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New();
4101 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4102 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4103 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4104 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4105 DataArrayIdType *cellsInM1ToRenumW4Tmp=0;
4106 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4107 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4108 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4109 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4110 DAInt grpIds=getGroupArr(-1,grpNameM1);
4111 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4112 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4113 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4114 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4115 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4116 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4117 m0->setCoords(tmp0->getCoords());
4118 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4119 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4120 m1->setCoords(m0->getCoords());
4121 _coords=m0->getCoords(); _coords->incrRef();
4122 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4123 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4124 DataArrayIdType * duplCells;
4125 m1->areCellsIncludedIn(m11, 0, duplCells);
4126 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4127 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4128 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4129 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4130 DAInt szOfCellGrpOfSameType(tmp00);
4131 DAInt idInMsOfCellGrpOfSameType(tmp11);
4133 newm1->setName(getName());
4134 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
4136 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4137 DAInt newFam=DataArrayIdType::New();
4138 newFam->alloc(newm1->getNumberOfCells(),1);
4139 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4140 // Positive ID for family of nodes, negative for all the rest.
4142 if (m1->getMeshDimension() == 0)
4143 idd=getMaxFamilyId()+1;
4145 idd=getMinFamilyId()-1;
4146 mcIdType globStart=0,start=0,end,globEnd;
4147 mcIdType nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4148 for(mcIdType i=0;i<nbOfChunks;i++)
4150 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4151 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4153 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4154 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4155 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4160 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4164 newm1->setCoords(getCoords());
4165 setMeshAtLevel(-1,newm1);
4166 setFamilyFieldArr(-1,newFam);
4167 std::string grpName2(grpNameM1); grpName2+="_dup";
4168 addFamily(grpName2,idd);
4169 addFamilyOnGrp(grpName2,grpName2);
4174 mcIdType newNbOfNodes=getCoords()->getNumberOfTuples();
4175 newFam=DataArrayIdType::New(); newFam->alloc(newNbOfNodes,1);
4176 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4177 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4181 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4183 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4184 it != _ms.end(); it++)
4187 (*it)->_rev_num = 0;
4189 nodesDuplicated=nodeIdsToDuplicate.retn();
4190 cellsModified=cellsToModifyConn0.retn();
4191 cellsNotModified=cellsToModifyConn1.retn();
4194 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4195 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4198 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4199 * \param [out] newCode retrieves the distribution of types after the call if true is returned
4200 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4202 * \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.
4203 * 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.
4205 bool MEDFileUMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
4207 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4208 std::vector<int> levs=getNonEmptyLevels();
4210 std::vector< const DataArrayIdType* > renumCellsSplited;//same than memorySaverIfThrow
4211 std::vector< MCAuto<DataArrayIdType> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4214 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4216 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4217 std::vector<mcIdType> code1=m->getDistributionOfTypes();
4218 end=PutInThirdComponentOfCodeOffset(code1,start);
4219 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4220 bool hasChanged=m->unPolyze();
4221 DataArrayIdType *fake=0;
4222 MCAuto<DataArrayIdType> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4223 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4225 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4228 MCAuto<DataArrayIdType> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4229 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4231 MCAuto<DataArrayIdType> famField2,numField2;
4232 const DataArrayIdType *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayIdType *>(famField); }
4233 const DataArrayIdType *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayIdType *>(numField); }
4234 setMeshAtLevel(*it,m);
4235 std::vector<mcIdType> code2=m->getDistributionOfTypes();
4236 end=PutInThirdComponentOfCodeOffset(code2,start);
4237 newCode.insert(newCode.end(),code2.begin(),code2.end());
4239 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4243 MCAuto<DataArrayIdType> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4244 setFamilyFieldArr(*it,newFamField);
4248 MCAuto<DataArrayIdType> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4249 setRenumFieldArr(*it,newNumField);
4254 newCode.insert(newCode.end(),code1.begin(),code1.end());
4260 MCAuto<DataArrayIdType> renumCells=DataArrayIdType::Aggregate(renumCellsSplited);
4261 MCAuto<DataArrayIdType> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4262 o2nRenumCell=o2nRenumCellRet.retn();
4267 /*! \cond HIDDEN_ITEMS */
4268 struct MEDLoaderAccVisit1
4270 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4271 mcIdType operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4272 mcIdType _new_nb_of_nodes;
4277 * 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.
4278 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4279 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4280 * -1 values in returned array means that the corresponding old node is no more used.
4282 * \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
4283 * is modified in \a this.
4284 * \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
4287 DataArrayIdType *MEDFileUMesh::zipCoords()
4289 const DataArrayDouble *coo(getCoords());
4291 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4292 mcIdType nbOfNodes(coo->getNumberOfTuples());
4293 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4294 std::vector<int> neLevs(getNonEmptyLevels());
4295 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4297 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4298 if(zeLev->isMeshStoredSplitByType())
4300 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4301 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4303 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4307 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4308 mesh->computeNodeIdsAlg(nodeIdsInUse);
4311 mcIdType nbrOfNodesInUse((mcIdType)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4312 if(nbrOfNodesInUse==nbOfNodes)
4313 return 0;//no need to update _part_coords
4314 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfNodes,1);
4315 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4316 MCAuto<DataArrayIdType> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4317 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4318 MCAuto<DataArrayIdType> newFamCoords;
4319 MCAuto<DataArrayAsciiChar> newNameCoords;
4320 if((const DataArrayIdType *)_fam_coords)
4321 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4322 MCAuto<DataArrayIdType> newNumCoords,newGlobalNumCoords;
4323 if(_num_coords.isNotNull())
4324 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4325 if(_global_num_coords.isNotNull())
4326 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4327 if(_name_coords.isNotNull())
4328 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4329 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4330 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4332 if((MEDFileUMeshSplitL1*)*it)
4334 (*it)->renumberNodesInConn(ret->begin());
4335 (*it)->setCoords(_coords);
4338 // updates _part_coords
4339 const PartDefinition *pc(_part_coords);
4342 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4343 _part_coords=tmpPD->composeWith(pc);
4349 * This method is the extension of MEDCouplingUMesh::computeFetchedNodeIds. Except that here all levels are considered here.
4351 * \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.
4353 DataArrayIdType *MEDFileUMesh::computeFetchedNodeIds() const
4355 std::vector<int> neLevs(this->getNonEmptyLevels());
4356 std::vector<bool> nodesHighlighted(this->getNumberOfNodes(),false);
4357 for(auto lev : neLevs)
4359 const MEDFileUMeshSplitL1 *zeLev(this->getMeshAtLevSafe(lev));
4360 zeLev->highlightUsedNodes(nodesHighlighted);
4362 return DataArrayIdType::BuildListOfSwitchedOn(nodesHighlighted);
4366 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4367 * The extraction of \a this is specified by the extractDef \a input map.
4368 * This map tells for each level of cells, the cells kept in the extraction.
4370 * \return - a new reference of DataArrayIdType that represents sorted node ids, the extraction is lying on.
4371 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4373 DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4375 std::vector<int> levs(getNonEmptyLevels());
4376 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4377 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4380 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4381 if((*it).second.isNull())
4382 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4385 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4387 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4388 throw INTERP_KERNEL::Exception(oss.str());
4390 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4391 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4392 mPart->computeNodeIdsAlg(fetchedNodes);
4394 return DataArrayIdType::BuildListOfSwitchedOn(fetchedNodes);
4398 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4400 * \return - a new reference of MEDFileUMesh
4401 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4403 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4405 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4406 std::vector<int> levs(getNonEmptyLevels());
4407 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4410 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4411 if((*it).second.isNull())
4412 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4415 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4417 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4418 throw INTERP_KERNEL::Exception(oss.str());
4420 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4421 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4422 ret->setMeshAtLevel((*it).first,mPart);
4423 const DataArrayIdType *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4426 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4427 ret->setFamilyFieldArr((*it).first,famPart);
4431 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4432 ret->setFamilyFieldArr((*it).first,numPart);
4435 std::map<int, MCAuto<DataArrayIdType> >::const_iterator it2(extractDef.find(1));
4436 if(it2!=extractDef.end())
4438 const DataArrayDouble *coo(ret->getCoords());
4440 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4441 MCAuto<DataArrayIdType> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4442 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4443 ret->setCoords(cooPart);
4444 const DataArrayIdType *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4447 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4448 ret->setFamilyFieldArr(1,famPart);
4452 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4453 ret->setFamilyFieldArr(1,numPart);
4455 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4459 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4460 m->renumberNodesInConn(o2nNodes->begin());
4461 ret->setMeshAtLevel((*it3).first,m);
4468 * This method performs an extrusion along a path defined by \a m1D.
4469 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4470 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4471 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4472 * This method scans all levels in \a this
4473 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4475 * \param [in] m1D - the mesh defining the extrusion path.
4476 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4477 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4479 * \sa MEDCouplingUMesh::buildExtrudedMesh
4481 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4484 if(getMeshDimension()!=2)
4485 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4486 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4487 m1D->checkConsistencyLight();
4488 if(m1D->getMeshDimension()!=1)
4489 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4490 mcIdType nbRep(m1D->getNumberOfCells());
4491 std::vector<int> levs(getNonEmptyLevels());
4492 std::vector<std::string> grps(getGroupsNames());
4493 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4494 DataArrayDouble *coords(0);
4495 std::size_t nbOfLevsOut(levs.size()+1);
4496 std::vector< MCAuto<DataArrayIdType> > o2ns(nbOfLevsOut);
4497 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4499 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4500 item=item->clone(false);
4501 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4502 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4503 tmp->changeSpaceDimension(3+(*lev),0.);
4504 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4505 zeList.push_back(elt);
4507 coords=elt->getCoords();
4510 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4511 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4513 (*it)->setName(getName());
4514 (*it)->setCoords(coords);
4516 for(std::size_t ii=0;ii!=zeList.size();ii++)
4519 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4522 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4523 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4524 MCAuto<DataArrayIdType> tmp(elt2->getNodalConnectivity()->deepCopy());
4525 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4526 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4527 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4528 std::vector<const MEDCouplingUMesh *> elts(3);
4529 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4530 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4531 elt->setName(getName());
4534 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4535 ret->setMeshAtLevel(lev,elt);
4537 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4538 endLev=endLev->clone(false); endLev->setCoords(coords);
4539 MCAuto<DataArrayIdType> tmp(endLev->getNodalConnectivity()->deepCopy());
4540 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4541 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4542 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4543 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4544 endLev->setName(getName());
4545 ret->setMeshAtLevel(levs.back()-1,endLev);
4547 for(std::size_t ii=0;ii!=zeList.size();ii++)
4550 std::vector< MCAuto<DataArrayIdType> > outGrps;
4551 std::vector< const DataArrayIdType * > outGrps2;
4554 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4556 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev+1,*grp));
4557 if(!grpArr->empty())
4559 MCAuto<DataArrayIdType> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4560 mcIdType offset0(zeList[ii]->getNumberOfCells());
4561 mcIdType offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4562 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4563 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4564 grpArr2->setName(oss.str());
4565 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4566 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4567 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4568 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4573 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4575 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev,*grp));
4576 if(!grpArr->empty())
4578 mcIdType nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4579 std::vector< MCAuto<DataArrayIdType> > grpArrs(nbRep);
4580 std::vector< const DataArrayIdType *> grpArrs2(nbRep);
4581 for(int iii=0;iii<nbRep;iii++)
4583 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4584 grpArrs2[iii]=grpArrs[iii];
4586 MCAuto<DataArrayIdType> grpArrExt(DataArrayIdType::Aggregate(grpArrs2));
4587 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4588 std::ostringstream grpName; grpName << *grp << "_extruded";
4589 grpArrExt->setName(grpName.str());
4590 outGrps.push_back(grpArrExt);
4591 outGrps2.push_back(grpArrExt);
4594 ret->setGroupsAtLevel(lev,outGrps2);
4596 std::vector< MCAuto<DataArrayIdType> > outGrps;
4597 std::vector< const DataArrayIdType * > outGrps2;
4598 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4600 MCAuto<DataArrayIdType> grpArr1(getGroupArr(levs.back(),*grp));
4601 if(grpArr1->empty())
4603 MCAuto<DataArrayIdType> grpArr2(grpArr1->deepCopy());
4604 std::ostringstream grpName; grpName << *grp << "_top";
4605 grpArr2->setName(grpName.str());
4606 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4607 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4608 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4610 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4615 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4616 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4617 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4619 * \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
4620 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4621 * \param [in] eps - detection threshold for coordinates.
4622 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4624 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4626 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4629 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4630 mcIdType initialNbNodes(getNumberOfNodes());
4631 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4632 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4634 MCAuto<DataArrayIdType> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4636 DataArrayDouble *zeCoords(m0->getCoords());
4637 ret->setMeshAtLevel(0,m0);
4638 std::vector<int> levs(getNonEmptyLevels());
4639 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4642 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4643 ret->setFamilyFieldArr(0,famFieldCpy);
4645 famField=getFamilyFieldAtLevel(1);
4648 MCAuto<DataArrayIdType> fam(DataArrayIdType::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4649 fam->fillWithZero();
4650 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4651 ret->setFamilyFieldArr(1,fam);
4653 ret->copyFamGrpMapsFrom(*this);
4654 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4655 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4659 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4660 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4661 if(m1->getMeshDimension()!=0)
4664 MCAuto<DataArrayIdType> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4665 }//kill unused notUsed var
4666 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4667 DataArrayIdType *b(0);
4668 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4669 MCAuto<DataArrayIdType> bSafe(b);
4672 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4673 throw INTERP_KERNEL::Exception(oss.str().c_str());
4675 b->applyLin(1,initialNbNodes);
4676 MCAuto<DataArrayIdType> l0(DataArrayIdType::New()); l0->alloc(initialNbNodes,1); l0->iota();
4677 std::vector<const DataArrayIdType *> v(2); v[0]=l0; v[1]=b;
4678 MCAuto<DataArrayIdType> renum(DataArrayIdType::Aggregate(v));
4679 m1->renumberNodesInConn(renum->begin());
4681 m1->setCoords(zeCoords);
4682 ret->setMeshAtLevel(*lev,m1);
4683 famField=getFamilyFieldAtLevel(*lev);
4686 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4687 ret->setFamilyFieldArr(*lev,famFieldCpy);
4694 * This method converts all quadratic cells in \a this into linear cells.
4695 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4696 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4698 * \param [in] eps - detection threshold for coordinates.
4699 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4701 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4703 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4706 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4707 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4708 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4709 m0->convertQuadraticCellsToLinear();
4711 DataArrayDouble *zeCoords(m0->getCoords());
4712 ret->setMeshAtLevel(0,m0);
4713 std::vector<int> levs(getNonEmptyLevels());
4714 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4717 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4718 ret->setFamilyFieldArr(0,famFieldCpy);
4720 famField=getFamilyFieldAtLevel(1);
4723 MCAuto<DataArrayIdType> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4724 ret->setFamilyFieldArr(1,fam);
4726 ret->copyFamGrpMapsFrom(*this);
4727 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4731 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4732 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4733 m1->convertQuadraticCellsToLinear();
4735 DataArrayIdType *b(0);
4736 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4737 MCAuto<DataArrayIdType> bSafe(b);
4740 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4741 throw INTERP_KERNEL::Exception(oss.str().c_str());
4743 m1->renumberNodesInConn(b->begin());
4744 m1->setCoords(zeCoords);
4745 ret->setMeshAtLevel(*lev,m1);
4746 famField=getFamilyFieldAtLevel(*lev);
4749 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4750 ret->setFamilyFieldArr(*lev,famFieldCpy);
4757 * Computes the symmetry of \a this.
4758 * \return a new object.
4760 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4762 MCAuto<MEDFileUMesh> ret(deepCopy());
4763 DataArrayDouble *myCoo(getCoords());
4766 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4767 ret->setCoordsForced(newCoo);
4773 * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
4774 * merged in such a way that the final mesh contain all of them.
4775 * \return a new object.
4777 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4780 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4781 std::size_t sz(meshes.size()),i(0);
4782 std::vector<const DataArrayDouble *> coos(sz);
4783 std::vector<const DataArrayIdType *> fam_coos(sz),num_coos(sz);
4784 for(auto it=meshes.begin();it!=meshes.end();it++,i++)
4787 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4788 coos[i]=(*it)->getCoords();
4789 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4790 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4792 const MEDFileUMesh *ref(meshes[0]);
4793 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4794 std::vector<int> levs(ref->getNonEmptyLevels());
4795 std::map<int, std::vector<const DataArrayIdType *> > m_fam,m_renum;
4796 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4797 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4798 std::map<std::string,mcIdType> famNumMap;
4799 std::map<mcIdType, std::string> famNumMap_rev;
4800 std::map<std::string, std::vector<std::string> > grpFamMap;
4801 std::set< MCAuto<DataArrayIdType> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
4803 // Identify min family number used:
4804 mcIdType min_fam_num(0);
4805 for(const auto& msh : meshes)
4807 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4808 for(const auto& it3 : locMap1)
4809 if(it3.second < min_fam_num)
4810 min_fam_num = it3.second;
4813 for(const auto& msh : meshes)
4815 if(msh->getSpaceDimension()!=spaceDim)
4816 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4817 if(msh->getMeshDimension()!=meshDim)
4818 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4819 if(msh->getNonEmptyLevels()!=levs)
4820 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4822 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4823 std::map<std::string, std::string> substitute;
4824 std::map<mcIdType, mcIdType> substituteN;
4825 bool fam_conflict(false);
4826 for(const auto& it3 : locMap1)
4828 const std::string& famName = it3.first;
4829 mcIdType famNum = it3.second;
4830 if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
4832 // Is it used by a group of the current mesh or a group from a previous mesh?
4833 // If not, this is OK (typically -1 familly).
4836 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4837 for(const auto& it4 : locMap2)
4839 const auto& famLst = it4.second;
4840 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4841 { used = true; break; }
4843 // Previous meshes ...
4845 for(const auto& it4 : grpFamMap)
4847 const auto& famLst = it4.second;
4848 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4849 { used = true; break; }
4853 { // Generate a new family name, and a new family number
4854 fam_conflict = true;
4855 std::ostringstream oss;
4856 oss << "Family_" << --min_fam_num; // New ID
4857 std::string new_name(oss.str());
4858 substitute[famName] = new_name;
4859 substituteN[famNum] = min_fam_num;
4860 famNumMap[new_name] = min_fam_num;
4861 famNumMap_rev[min_fam_num] = new_name;
4864 famNumMap[famName] = famNum;
4865 famNumMap_rev[famNum] = famName;
4868 for(const auto& level : levs)
4870 MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
4871 m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
4872 m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
4874 // Family field - substitute new family number if needed:
4877 DataArrayIdType* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
4878 mem_cleanup.insert(MCAuto<DataArrayIdType>(dai)); // Make sure array will decrRef() at end of method
4879 for (const auto& subN : substituteN)
4880 dai->changeValue(subN.first, subN.second);
4881 m_fam[level].push_back(dai);
4884 m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
4887 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4888 for(const auto& grpItem : locMap2)
4890 const std::string& grpName = grpItem.first;
4891 std::vector<std::string> famLst;
4892 // Substitute family name in group description if needed:
4895 famLst = grpItem.second;
4896 for (const auto& sub : substitute)
4897 std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
4900 famLst = grpItem.second;
4902 // Potentially merge groups (if same name):
4903 const auto& it = grpFamMap.find(grpName);
4904 if (it != grpFamMap.end())
4906 // Group already exists, merge should be done. Normally we whould never
4907 // have twice the same family name in famLstCur and famLst since we dealt with family number
4908 // conflict just above ...
4909 std::vector<std::string>& famLstCur = (*it).second;
4910 famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
4913 grpFamMap[grpName] = famLst;
4916 // Easy part : nodes
4917 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4918 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4919 ret->setCoords(coo);
4920 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayIdType *)0)==fam_coos.end())
4922 MCAuto<DataArrayIdType> fam_coo(DataArrayIdType::Aggregate(fam_coos));
4923 ret->setFamilyFieldArr(1,fam_coo);
4925 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayIdType *)0)==num_coos.end())
4927 MCAuto<DataArrayIdType> num_coo(DataArrayIdType::Aggregate(num_coos));
4928 ret->setRenumFieldArr(1,num_coo);
4931 for(const auto& level : levs)
4933 auto it2(m_mesh.find(level));
4934 if(it2==m_mesh.end())
4935 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4936 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4937 mesh->setCoords(coo); mesh->setName(ref->getName());
4938 MCAuto<DataArrayIdType> renum(mesh->sortCellsInMEDFileFrmt());
4939 ret->setMeshAtLevel(level,mesh);
4940 auto it3(m_fam.find(level)),it4(m_renum.find(level));
4941 if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
4942 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
4943 if(it4==m_renum.end())
4944 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
4945 // Set new family field if it was defined for all input meshes
4946 const std::vector<const DataArrayIdType *>& fams((*it3).second);
4947 if(std::find(fams.begin(),fams.end(),(const DataArrayIdType *)0)==fams.end())
4949 MCAuto<DataArrayIdType> famm(DataArrayIdType::Aggregate(fams));
4950 famm->renumberInPlace(renum->begin());
4951 ret->setFamilyFieldArr(level,famm);
4953 // Set optional number field if defined for all input meshes:
4954 const std::vector<const DataArrayIdType *>& renums((*it4).second);
4955 if(std::find(renums.begin(),renums.end(),(const DataArrayIdType *)0)==renums.end())
4957 MCAuto<DataArrayIdType> renumm(DataArrayIdType::Aggregate(renums));
4958 renumm->renumberInPlace(renum->begin());
4959 ret->setRenumFieldArr(level,renumm);
4963 ret->setFamilyInfo(famNumMap);
4964 ret->setGroupInfo(grpFamMap);
4965 ret->setName(ref->getName());
4969 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4971 if(getMeshDimension()!=3)
4972 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4973 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4974 if(m3D.isNull() || m2D.isNull())
4975 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4976 mcIdType zeId(std::numeric_limits<med_int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4977 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4981 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4983 clearNonDiscrAttributes();
4984 forceComputationOfParts();
4985 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4986 std::vector<mcIdType> layer0;
4987 layer0.push_back(getAxisType());//0 i
4988 layer0.push_back(_order); //1 i
4989 layer0.push_back(_iteration);//2 i
4990 layer0.push_back(getSpaceDimension());//3 i
4991 tinyDouble.push_back(_time);//0 d
4992 tinyStr.push_back(_name);//0 s
4993 tinyStr.push_back(_desc_name);//1 s
4994 for(int i=0;i<getSpaceDimension();i++)
4995 tinyStr.push_back(_coords->getInfoOnComponent(i));
4996 layer0.push_back(ToIdType(_families.size()));//4 i <- key info aa layer#0
4997 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
4999 tinyStr.push_back((*it).first);
5000 layer0.push_back((*it).second);
5002 layer0.push_back((mcIdType)_groups.size());//4+aa i <- key info bb layer#0
5003 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
5005 layer0.push_back(ToIdType((*it0).second.size()));
5006 tinyStr.push_back((*it0).first);
5007 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
5008 tinyStr.push_back(*it1);
5010 // sizeof(layer0)==4+aa+1+bb layer#0
5011 bigArrayD=_coords;// 0 bd
5012 bigArraysI.push_back(_fam_coords);// 0 bi
5013 bigArraysI.push_back(_num_coords);// 1 bi
5014 const PartDefinition *pd(_part_coords);
5016 layer0.push_back(-1);
5019 std::vector<mcIdType> tmp0;
5020 pd->serialize(tmp0,bigArraysI);
5021 tinyInt.push_back(ToIdType(tmp0.size()));
5022 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
5025 std::vector<mcIdType> layer1;
5026 std::vector<int> levs(getNonEmptyLevels());
5027 layer1.push_back((mcIdType)levs.size());// 0 i <- key
5028 layer1.insert(layer1.end(),levs.begin(),levs.end());
5029 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
5031 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
5032 lev->serialize(layer1,bigArraysI);
5034 // put layers all together.
5035 tinyInt.push_back(ToIdType(layer0.size()));
5036 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
5037 tinyInt.push_back(ToIdType(layer1.size()));
5038 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
5041 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr,
5042 std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5044 mcIdType sz0(tinyInt[0]);
5045 std::vector<mcIdType> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
5046 mcIdType sz1(tinyInt[sz0+1]);
5047 std::vector<mcIdType> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
5049 std::reverse(layer0.begin(),layer0.end());
5050 std::reverse(layer1.begin(),layer1.end());
5051 std::reverse(tinyDouble.begin(),tinyDouble.end());
5052 std::reverse(tinyStr.begin(),tinyStr.end());
5053 std::reverse(bigArraysI.begin(),bigArraysI.end());
5055 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
5056 _order=FromIdType<int>(layer0.back()); layer0.pop_back();
5057 _iteration=FromIdType<int>(layer0.back()); layer0.pop_back();
5058 mcIdType spaceDim(layer0.back()); layer0.pop_back();
5059 _time=tinyDouble.back(); tinyDouble.pop_back();
5060 _name=tinyStr.back(); tinyStr.pop_back();
5061 _desc_name=tinyStr.back(); tinyStr.pop_back();
5062 _coords=bigArrayD; _coords->rearrange(spaceDim);
5063 for(int i=0;i<spaceDim;i++)
5065 _coords->setInfoOnComponent(i,tinyStr.back());
5068 mcIdType nbOfFams(layer0.back()); layer0.pop_back();
5070 for(mcIdType i=0;i<nbOfFams;i++)
5072 _families[tinyStr.back()]=layer0.back();
5073 tinyStr.pop_back(); layer0.pop_back();
5075 mcIdType nbGroups(layer0.back()); layer0.pop_back();
5077 for(mcIdType i=0;i<nbGroups;i++)
5079 std::string grpName(tinyStr.back()); tinyStr.pop_back();
5080 mcIdType nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
5081 std::vector<std::string> fams(nbOfFamsOnGrp);
5082 for(mcIdType j=0;j<nbOfFamsOnGrp;j++)
5084 fams[j]=tinyStr.back(); tinyStr.pop_back();
5086 _groups[grpName]=fams;
5088 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
5089 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
5091 mcIdType isPd(layer0.back()); layer0.pop_back();
5094 std::vector<mcIdType> tmp0(layer0.begin(),layer0.begin()+isPd);
5095 layer0.erase(layer0.begin(),layer0.begin()+isPd);
5096 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
5099 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
5101 mcIdType nbLevs(layer1.back()); layer1.pop_back();
5102 std::vector<mcIdType> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
5104 mcIdType maxLev(-(*std::min_element(levs.begin(),levs.end())));
5105 _ms.resize(maxLev+1);
5106 for(mcIdType i=0;i<nbLevs;i++)
5108 mcIdType lev(levs[i]);
5110 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
5115 * Adds a group of nodes to \a this mesh.
5116 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5117 * The ids should be sorted and different each other (MED file norm).
5119 * \warning this method can alter default "FAMILLE_ZERO" family.
5120 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5122 * \throw If the node coordinates array is not set.
5123 * \throw If \a ids == \c NULL.
5124 * \throw If \a ids->getName() == "".
5125 * \throw If \a ids does not respect the MED file norm.
5126 * \throw If a group with name \a ids->getName() already exists.
5128 void MEDFileUMesh::addNodeGroup(const DataArrayIdType *ids)
5130 const DataArrayDouble *coords(_coords);
5132 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
5133 mcIdType nbOfNodes(coords->getNumberOfTuples());
5134 if(_fam_coords.isNull())
5135 { _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
5137 addGroupUnderground(true,ids,_fam_coords);
5141 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5143 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5144 * The ids should be sorted and different each other (MED file norm).
5146 * \warning this method can alter default "FAMILLE_ZERO" family.
5147 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5149 * \throw If the node coordinates array is not set.
5150 * \throw If \a ids == \c NULL.
5151 * \throw If \a ids->getName() == "".
5152 * \throw If \a ids does not respect the MED file norm.
5153 * \throw If a group with name \a ids->getName() already exists.
5155 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
5157 std::vector<int> levs(getNonEmptyLevelsExt());
5158 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
5160 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
5161 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
5163 if(meshDimRelToMaxExt==1)
5164 { addNodeGroup(ids); return ; }
5165 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
5166 DataArrayIdType *fam(lev->getOrCreateAndGetFamilyField());
5167 addGroupUnderground(false,ids,fam);
5171 * Changes a name of a family specified by its id.
5172 * \param [in] id - the id of the family of interest.
5173 * \param [in] newFamName - the new family name.
5174 * \throw If no family with the given \a id exists.
5176 void MEDFileUMesh::setFamilyNameAttachedOnId(mcIdType id, const std::string& newFamName)
5178 std::string oldName=getFamilyNameGivenId(id);
5179 _families.erase(oldName);
5180 _families[newFamName]=id;
5184 * Removes a mesh of a given dimension.
5185 * \param [in] meshDimRelToMax - the relative dimension of interest.
5186 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
5188 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
5190 std::vector<int> levSet=getNonEmptyLevels();
5191 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
5192 if(it==levSet.end())
5193 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
5194 int pos=(-meshDimRelToMax);
5199 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
5200 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5201 * \param [in] m - the new mesh to set.
5202 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5204 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5205 * another node coordinates array.
5206 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5207 * to the existing meshes of other levels of \a this mesh.
5209 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5211 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5212 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5216 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5217 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5218 * \param [in] m - the new mesh to set.
5219 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5220 * writing \a this mesh in a MED file.
5221 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5223 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5224 * another node coordinates array.
5225 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5226 * to the existing meshes of other levels of \a this mesh.
5228 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5230 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5231 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5234 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5236 dealWithTinyInfo(m);
5237 std::vector<int> levSet=getNonEmptyLevels();
5238 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5240 if((DataArrayDouble *)_coords==0)
5242 DataArrayDouble *c=m->getCoords();
5247 if(m->getCoords()!=_coords)
5248 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5249 int sz=(-meshDimRelToMax)+1;
5250 if(sz>=(int)_ms.size())
5252 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5256 return _ms[-meshDimRelToMax];
5260 * This method allows to set at once the content of different levels in \a this.
5261 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5263 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5264 * \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.
5265 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5267 * \throw If \a there is a null pointer in \a ms.
5268 * \sa MEDFileUMesh::setMeshAtLevel
5270 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5274 const MEDCouplingUMesh *mRef=ms[0];
5276 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5277 std::string name(mRef->getName());
5278 const DataArrayDouble *coo(mRef->getCoords());
5281 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5283 const MEDCouplingUMesh *cur(*it);
5285 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5286 if(coo!=cur->getCoords())
5287 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5288 int mdim=cur->getMeshDimension();
5289 zeDim=std::max(zeDim,mdim);
5290 if(s.find(mdim)!=s.end())
5291 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5293 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5295 int mdim=(*it)->getMeshDimension();
5296 setName((*it)->getName());
5297 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5303 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5304 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5305 * The given meshes must share the same node coordinates array.
5306 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5307 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5308 * create in \a this mesh.
5309 * \throw If \a ms is empty.
5310 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5311 * to the existing meshes of other levels of \a this mesh.
5312 * \throw If the meshes in \a ms do not share the same node coordinates array.
5313 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5314 * of the given meshes.
5315 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5316 * \throw If names of some meshes in \a ms are equal.
5317 * \throw If \a ms includes a mesh with an empty name.
5319 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5322 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5323 int sz=(-meshDimRelToMax)+1;
5324 if(sz>=(int)_ms.size())
5326 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5327 DataArrayDouble *coo=checkMultiMesh(ms);
5328 if((DataArrayDouble *)_coords==0)
5334 if((DataArrayDouble *)_coords!=coo)
5335 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5336 std::vector<DataArrayIdType *> corr;
5337 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5338 std::vector< MCAuto<DataArrayIdType> > corr3(corr.begin(),corr.end());
5339 setMeshAtLevel(meshDimRelToMax,m,renum);
5340 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5341 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5345 * Creates groups at a given level in \a this mesh from a sequence of
5346 * meshes each representing a group.
5347 * The given meshes must share the same node coordinates array.
5348 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5349 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5350 * create in \a this mesh.
5351 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5353 * \throw If \a ms is empty.
5354 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5355 * to the existing meshes of other levels of \a this mesh.
5356 * \throw If the meshes in \a ms do not share the same node coordinates array.
5357 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5358 * of the given meshes.
5359 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5360 * \throw If names of some meshes in \a ms are equal.
5361 * \throw If \a ms includes a mesh with an empty name.
5363 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5366 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5367 int sz=(-meshDimRelToMax)+1;
5368 if(sz>=(int)_ms.size())
5370 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5371 DataArrayDouble *coo=checkMultiMesh(ms);
5372 if((DataArrayDouble *)_coords==0)
5378 if((DataArrayDouble *)_coords!=coo)
5379 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5380 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5381 std::vector< MCAuto<DataArrayIdType> > corr(ms.size());
5383 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5385 DataArrayIdType *arr=0;
5386 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5390 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5391 throw INTERP_KERNEL::Exception(oss.str().c_str());
5394 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5395 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5398 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5400 const DataArrayDouble *ret=ms[0]->getCoords();
5401 int mdim=ms[0]->getMeshDimension();
5402 for(unsigned int i=1;i<ms.size();i++)
5404 ms[i]->checkConsistencyLight();
5405 if(ms[i]->getCoords()!=ret)
5406 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5407 if(ms[i]->getMeshDimension()!=mdim)
5408 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5410 return const_cast<DataArrayDouble *>(ret);
5414 * Sets the family field of a given relative dimension.
5415 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5416 * the family field is set.
5417 * \param [in] famArr - the array of the family field.
5418 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5419 * \throw If \a famArr has an invalid size.
5421 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5423 if(meshDimRelToMaxExt==1)
5430 DataArrayDouble *coo(_coords);
5432 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5433 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5434 _fam_coords.takeRef(famArr);
5437 if(meshDimRelToMaxExt>1)
5438 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5439 int traducedRk=-meshDimRelToMaxExt;
5440 if(traducedRk>=(int)_ms.size())
5441 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5442 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5443 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5444 return _ms[traducedRk]->setFamilyArr(famArr);
5448 * Sets the optional numbers of mesh entities of a given dimension.
5449 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5450 * \param [in] renumArr - the array of the numbers.
5451 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5452 * \throw If \a renumArr has an invalid size.
5454 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5456 if(meshDimRelToMaxExt==1)
5460 _num_coords.nullify();
5461 _rev_num_coords.nullify();
5464 if(_coords.isNull())
5465 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5466 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5467 _num_coords.takeRef(renumArr);
5471 if(meshDimRelToMaxExt>1)
5472 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5473 int traducedRk=-meshDimRelToMaxExt;
5474 if(traducedRk>=(int)_ms.size())
5475 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5476 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5477 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5478 return _ms[traducedRk]->setRenumArr(renumArr);
5482 * Sets the optional names of mesh entities of a given dimension.
5483 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5484 * \param [in] nameArr - the array of the names.
5485 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5486 * \throw If \a nameArr has an invalid size.
5488 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5490 if(meshDimRelToMaxExt==1)
5497 DataArrayDouble *coo(_coords);
5499 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5500 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5501 _name_coords.takeRef(nameArr);
5504 if(meshDimRelToMaxExt>1)
5505 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5506 int traducedRk=-meshDimRelToMaxExt;
5507 if(traducedRk>=(int)_ms.size())
5508 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5509 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5510 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5511 return _ms[traducedRk]->setNameArr(nameArr);
5514 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
5516 if(meshDimRelToMaxExt!=1)
5517 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5519 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5520 _global_num_coords.takeRef(globalNumArr);
5523 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5525 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5526 if((const MEDFileUMeshSplitL1 *)(*it))
5527 (*it)->synchronizeTinyInfo(*this);
5531 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5533 void MEDFileUMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
5535 DataArrayIdType *arr=_fam_coords;
5537 arr->changeValue(oldId,newId);
5538 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5540 MEDFileUMeshSplitL1 *sp=(*it);
5543 sp->changeFamilyIdArr(oldId,newId);
5548 std::list< MCAuto<DataArrayIdType> > MEDFileUMesh::getAllNonNullFamilyIds() const
5550 std::list< MCAuto<DataArrayIdType> > ret;
5551 const DataArrayIdType *da(_fam_coords);
5553 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5554 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5556 const MEDFileUMeshSplitL1 *elt(*it);
5559 da=elt->getFamilyField();
5561 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5567 void MEDFileUMesh::computeRevNum() const
5569 if(_num_coords.isNotNull())
5572 mcIdType maxValue=_num_coords->getMaxValue(pos);
5573 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5577 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5579 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5582 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5584 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5585 ret.push_back((const DataArrayIdType *)_fam_nodes);
5586 ret.push_back((const DataArrayIdType *)_num_nodes);
5587 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5588 ret.push_back((const DataArrayIdType *)_fam_cells);
5589 ret.push_back((const DataArrayIdType *)_num_cells);
5590 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5591 ret.push_back((const DataArrayIdType *)_fam_faces);
5592 ret.push_back((const DataArrayIdType *)_num_faces);
5593 ret.push_back((const DataArrayIdType *)_rev_num_nodes);
5594 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5595 ret.push_back((const DataArrayIdType *)_rev_num_cells);
5596 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5600 mcIdType MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5602 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5603 if((const DataArrayIdType *)_fam_nodes)
5605 mcIdType val=_fam_nodes->getMaxValue(tmp);
5606 ret=std::max(ret,std::abs(val));
5608 if((const DataArrayIdType *)_fam_cells)
5610 mcIdType val=_fam_cells->getMaxValue(tmp);
5611 ret=std::max(ret,std::abs(val));
5613 if((const DataArrayIdType *)_fam_faces)
5615 mcIdType val=_fam_faces->getMaxValue(tmp);
5616 ret=std::max(ret,std::abs(val));
5621 mcIdType MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5623 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5624 if((const DataArrayIdType *)_fam_nodes)
5626 mcIdType val=_fam_nodes->getMaxValue(tmp);
5627 ret=std::max(ret,val);
5629 if((const DataArrayIdType *)_fam_cells)
5631 mcIdType val=_fam_cells->getMaxValue(tmp);
5632 ret=std::max(ret,val);
5634 if((const DataArrayIdType *)_fam_faces)
5636 mcIdType val=_fam_faces->getMaxValue(tmp);
5637 ret=std::max(ret,val);
5642 mcIdType MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5644 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
5645 if((const DataArrayIdType *)_fam_nodes)
5647 mcIdType val=_fam_nodes->getMinValue(tmp);
5648 ret=std::min(ret,val);
5650 if((const DataArrayIdType *)_fam_cells)
5652 mcIdType val=_fam_cells->getMinValue(tmp);
5653 ret=std::min(ret,val);
5655 if((const DataArrayIdType *)_fam_faces)
5657 mcIdType val=_fam_faces->getMinValue(tmp);
5658 ret=std::min(ret,val);
5663 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5665 if(!MEDFileMesh::isEqual(other,eps,what))
5667 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5670 what="Mesh types differ ! This is structured and other is NOT !";
5673 const DataArrayIdType *famc1=_fam_nodes;
5674 const DataArrayIdType *famc2=otherC->_fam_nodes;
5675 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5677 what="Mismatch of families arr on nodes ! One is defined and not other !";
5682 bool ret=famc1->isEqual(*famc2);
5685 what="Families arr on nodes differ !";
5690 famc2=otherC->_fam_cells;
5691 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5693 what="Mismatch of families arr on cells ! One is defined and not other !";
5698 bool ret=famc1->isEqual(*famc2);
5701 what="Families arr on cells differ !";
5706 famc2=otherC->_fam_faces;
5707 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5709 what="Mismatch of families arr on faces ! One is defined and not other !";
5714 bool ret=famc1->isEqual(*famc2);
5717 what="Families arr on faces differ !";
5722 famc2=otherC->_num_nodes;
5723 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5725 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5730 bool ret=famc1->isEqual(*famc2);
5733 what="Numbering arr on nodes differ !";
5738 famc2=otherC->_num_cells;
5739 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5741 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5746 bool ret=famc1->isEqual(*famc2);
5749 what="Numbering arr on cells differ !";
5754 famc2=otherC->_num_faces;
5755 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5757 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5762 bool ret=famc1->isEqual(*famc2);
5765 what="Numbering arr on faces differ !";
5769 const DataArrayAsciiChar *d1=_names_cells;
5770 const DataArrayAsciiChar *d2=otherC->_names_cells;
5771 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5773 what="Mismatch of naming arr on cells ! One is defined and not other !";
5778 bool ret=d1->isEqual(*d2);
5781 what="Naming arr on cells differ !";
5786 d2=otherC->_names_faces;
5787 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5789 what="Mismatch of naming arr on faces ! One is defined and not other !";
5794 bool ret=d1->isEqual(*d2);
5797 what="Naming arr on faces differ !";
5802 d2=otherC->_names_nodes;
5803 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5805 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5810 bool ret=d1->isEqual(*d2);
5813 what="Naming arr on nodes differ !";
5820 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5822 MEDFileMesh::clearNonDiscrAttributes();
5823 const DataArrayIdType *tmp=_fam_nodes;
5825 (const_cast<DataArrayIdType *>(tmp))->setName("");
5828 (const_cast<DataArrayIdType *>(tmp))->setName("");
5831 (const_cast<DataArrayIdType *>(tmp))->setName("");
5834 (const_cast<DataArrayIdType *>(tmp))->setName("");
5837 (const_cast<DataArrayIdType *>(tmp))->setName("");
5840 (const_cast<DataArrayIdType *>(tmp))->setName("");
5844 * Returns ids of mesh entities contained in given families of a given dimension.
5845 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5847 * \param [in] fams - the names of the families of interest.
5848 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5849 * returned instead of ids.
5850 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
5851 * numbers, if available and required, of mesh entities of the families. The caller
5852 * is to delete this array using decrRef() as it is no more needed.
5853 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5855 DataArrayIdType *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5857 std::vector<mcIdType> famIds(getFamiliesIds(fams));
5858 switch(meshDimRelToMaxExt)
5862 if((const DataArrayIdType *)_fam_nodes)
5864 MCAuto<DataArrayIdType> da;
5866 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5868 da=_fam_nodes->findIdsEqualList(0,0);
5870 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5875 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5880 if((const DataArrayIdType *)_fam_cells)
5882 MCAuto<DataArrayIdType> da;
5884 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5886 da=_fam_cells->findIdsEqualList(0,0);
5888 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5893 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5898 if((const DataArrayIdType *)_fam_faces)
5900 MCAuto<DataArrayIdType> da;
5902 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5904 da=_fam_faces->findIdsEqualList(0,0);
5906 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5911 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5915 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5917 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5921 * Sets the family field of a given relative dimension.
5922 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5923 * the family field is set.
5924 * \param [in] famArr - the array of the family field.
5925 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5926 * \throw If \a famArr has an invalid size.
5927 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5929 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5931 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5933 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5934 switch(meshDimRelToMaxExt)
5938 mcIdType nbCells(mesh->getNumberOfCells());
5940 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5946 mcIdType nbNodes(mesh->getNumberOfNodes());
5948 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5954 mcIdType nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5956 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5961 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5968 * Sets the optional numbers of mesh entities of a given dimension.
5969 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5970 * \param [in] renumArr - the array of the numbers.
5971 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5972 * \throw If \a renumArr has an invalid size.
5973 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5975 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5977 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5979 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5980 switch(meshDimRelToMaxExt)
5984 mcIdType nbCells=mesh->getNumberOfCells();
5985 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5986 _num_cells=renumArr;
5991 mcIdType nbNodes=mesh->getNumberOfNodes();
5992 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5993 _num_nodes=renumArr;
5998 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5999 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
6000 _num_faces=renumArr;
6004 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
6007 renumArr->incrRef();
6011 * Sets the optional names of mesh entities of a given dimension.
6012 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6013 * \param [in] nameArr - the array of the names.
6014 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6015 * \throw If \a nameArr has an invalid size.
6017 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
6019 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
6021 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
6022 switch(meshDimRelToMaxExt)
6026 mcIdType nbCells=mesh->getNumberOfCells();
6027 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
6028 _names_cells=nameArr;
6033 mcIdType nbNodes=mesh->getNumberOfNodes();
6034 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
6035 _names_nodes=nameArr;
6040 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6041 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
6042 _names_faces=nameArr;
6045 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6051 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
6053 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
6057 * Adds a group of nodes to \a this mesh.
6058 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6059 * The ids should be sorted and different each other (MED file norm).
6061 * \warning this method can alter default "FAMILLE_ZERO" family.
6062 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6064 * \throw If the node coordinates array is not set.
6065 * \throw If \a ids == \c NULL.
6066 * \throw If \a ids->getName() == "".
6067 * \throw If \a ids does not respect the MED file norm.
6068 * \throw If a group with name \a ids->getName() already exists.
6070 void MEDFileStructuredMesh::addNodeGroup(const DataArrayIdType *ids)
6076 * Adds a group of nodes/cells/faces/edges to \a this mesh.
6078 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6079 * The ids should be sorted and different each other (MED file norm).
6081 * \warning this method can alter default "FAMILLE_ZERO" family.
6082 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6084 * \throw If the node coordinates array is not set.
6085 * \throw If \a ids == \c NULL.
6086 * \throw If \a ids->getName() == "".
6087 * \throw If \a ids does not respect the MED file norm.
6088 * \throw If a group with name \a ids->getName() already exists.
6090 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
6092 DataArrayIdType *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
6093 addGroupUnderground(false,ids,fam);
6098 * Returns the family field for mesh entities of a given dimension.
6099 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6100 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6101 * each mesh entity belongs to. It can be \c NULL.
6102 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6104 const DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
6106 switch(meshDimRelToMaxExt)
6115 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6120 * Returns the family field for mesh entities of a given dimension.
6121 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6122 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6123 * each mesh entity belongs to. It can be \c NULL.
6124 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6126 DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
6128 switch(meshDimRelToMaxExt)
6137 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6142 * Returns the optional numbers of mesh entities of a given dimension.
6143 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6144 * \return const DataArrayIdType * - the array of the entity numbers.
6145 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6146 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6148 const DataArrayIdType *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
6150 switch(meshDimRelToMaxExt)
6159 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6164 * Returns the optional numbers of mesh entities of a given dimension transformed using
6165 * DataArrayIdType::invertArrayN2O2O2N().
6166 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6167 * \return const DataArrayIdType * - the array of the entity numbers transformed using
6168 * DataArrayIdType::invertArrayN2O2O2N().
6169 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6170 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6172 const DataArrayIdType *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
6174 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
6175 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
6176 if(meshDimRelToMaxExt==0)
6178 if((const DataArrayIdType *)_num_cells)
6181 mcIdType maxValue=_num_cells->getMaxValue(pos);
6182 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
6183 return _rev_num_cells;
6186 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
6190 if((const DataArrayIdType *)_num_nodes)
6193 mcIdType maxValue=_num_nodes->getMaxValue(pos);
6194 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
6195 return _rev_num_nodes;
6198 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6202 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6204 switch(meshDimRelToMaxExt)
6207 return _names_cells;
6209 return _names_nodes;
6211 return _names_faces;
6213 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6217 MCAuto<DataArrayIdType> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6219 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6223 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6224 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6226 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6228 std::vector<int> ret(1);
6233 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6234 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6236 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6238 std::vector<int> ret(2);
6244 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6246 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6248 std::vector<int> ret;
6249 const DataArrayIdType *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6260 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6262 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6264 std::vector<int> ret;
6265 const DataArrayIdType *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6276 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6278 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6280 std::vector<int> ret;
6281 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6292 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6294 bool MEDFileStructuredMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
6296 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6300 void MEDFileStructuredMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
6302 DataArrayIdType *arr=_fam_nodes;
6304 arr->changeValue(oldId,newId);
6307 arr->changeValue(oldId,newId);
6310 arr->changeValue(oldId,newId);
6313 std::list< MCAuto<DataArrayIdType> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6315 std::list< MCAuto<DataArrayIdType> > ret;
6316 const DataArrayIdType *da(_fam_nodes);
6318 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6321 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6324 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6328 void MEDFileStructuredMesh::deepCpyAttributes()
6330 if((const DataArrayIdType*)_fam_nodes)
6331 _fam_nodes=_fam_nodes->deepCopy();
6332 if((const DataArrayIdType*)_num_nodes)
6333 _num_nodes=_num_nodes->deepCopy();
6334 if((const DataArrayAsciiChar*)_names_nodes)
6335 _names_nodes=_names_nodes->deepCopy();
6336 if((const DataArrayIdType*)_fam_cells)
6337 _fam_cells=_fam_cells->deepCopy();
6338 if((const DataArrayIdType*)_num_cells)
6339 _num_cells=_num_cells->deepCopy();
6340 if((const DataArrayAsciiChar*)_names_cells)
6341 _names_cells=_names_cells->deepCopy();
6342 if((const DataArrayIdType*)_fam_faces)
6343 _fam_faces=_fam_faces->deepCopy();
6344 if((const DataArrayIdType*)_num_faces)
6345 _num_faces=_num_faces->deepCopy();
6346 if((const DataArrayAsciiChar*)_names_faces)
6347 _names_faces=_names_faces->deepCopy();
6348 if((const DataArrayIdType*)_rev_num_nodes)
6349 _rev_num_nodes=_rev_num_nodes->deepCopy();
6350 if((const DataArrayIdType*)_rev_num_cells)
6351 _rev_num_cells=_rev_num_cells->deepCopy();
6355 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6357 * \return a pointer to cartesian mesh that need to be managed by the caller.
6358 * \warning the returned pointer has to be managed by the caller.
6362 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6363 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6364 * \param [in] renum - it must be \c false.
6365 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6366 * delete using decrRef() as it is no more needed.
6368 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6372 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6373 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6374 switch(meshDimRelToMax)
6380 return const_cast<MEDCouplingStructuredMesh *>(m);
6385 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6386 buildMinusOneImplicitPartIfNeeded();
6387 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6393 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6397 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6399 std::vector<mcIdType> ret;
6400 const DataArrayIdType *famCells(_fam_cells),*famFaces(_fam_faces);
6401 if(famCells && famCells->presenceOfValue(ret))
6403 if(famFaces && famFaces->presenceOfValue(ret))
6408 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6410 std::vector<mcIdType> ret(getFamsNonEmptyLevels(fams));
6411 const DataArrayIdType *famNodes(_fam_nodes);
6412 if(famNodes && famNodes->presenceOfValue(ret))
6418 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6419 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6420 * \return mcIdType - the number of entities.
6421 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6423 mcIdType MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6425 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6427 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6428 switch(meshDimRelToMaxExt)
6431 return cmesh->getNumberOfCells();
6433 return cmesh->getNumberOfNodes();
6435 return cmesh->getNumberOfCellsOfSubLevelMesh();
6437 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6441 mcIdType MEDFileStructuredMesh::getNumberOfNodes() const
6443 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6445 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6446 return cmesh->getNumberOfNodes();
6449 mcIdType MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6451 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6453 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6454 switch(meshDimRelToMaxExt)
6457 return cmesh->getNumberOfCells();
6459 return cmesh->getNumberOfCellsOfSubLevelMesh();
6461 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6465 bool MEDFileStructuredMesh::hasImplicitPart() const
6471 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6473 mcIdType MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6475 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6476 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6479 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6480 if(cm.getReverseExtrudedType()!=gt)
6481 throw INTERP_KERNEL::Exception(MSG);
6482 buildImplicitPart();
6483 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6487 if(gt!=zeFaceMesh->getCellModelEnum())
6488 throw INTERP_KERNEL::Exception(MSG);
6489 return zeFaceMesh->getNumberOfCells();
6493 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6495 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6497 buildImplicitPart();
6500 void MEDFileStructuredMesh::buildImplicitPart() const
6502 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6504 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6505 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6508 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6510 _faces_if_necessary=0;
6514 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6515 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6517 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6519 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6522 return _faces_if_necessary;
6525 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6527 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6529 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6530 switch(meshDimRelToMax)
6534 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6539 int mdim(cmesh->getMeshDimension());
6541 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6542 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6546 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6550 mcIdType MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6552 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6555 return getNumberOfCellsAtLevel(0);
6558 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6560 if(st.getNumberOfItems()!=1)
6561 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 !");
6562 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6563 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6564 if(getNumberOfNodes()!=(mcIdType)nodesFetched.size())
6565 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6566 if(st[0].getPflName().empty())
6568 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6571 const DataArrayIdType *arr(globs->getProfile(st[0].getPflName()));
6572 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6573 mcIdType sz(ToIdType(nodesFetched.size()));
6574 for(const mcIdType *work=arr->begin();work!=arr->end();work++)
6576 std::vector<mcIdType> conn;
6577 cmesh->getNodeIdsOfCell(*work,conn);
6578 for(std::vector<mcIdType>::const_iterator it=conn.begin();it!=conn.end();it++)
6579 if(*it>=0 && *it<sz)
6580 nodesFetched[*it]=true;
6582 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6586 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6588 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6592 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6593 MCAuto<DataArrayIdType>& famCells, MCAuto<DataArrayIdType>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6595 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6596 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6597 mcIdType nbOfElt(0);
6598 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6601 if(!mrs || mrs->isCellFamilyFieldReading())
6603 MCAuto<DataArrayMedInt> miFamCells=DataArrayMedInt::New();
6604 miFamCells->alloc(nbOfElt,1);
6605 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miFamCells->getPointer()));
6606 famCells = FromMedIntArray<mcIdType>( miFamCells );
6609 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6612 if(!mrs || mrs->isCellNumFieldReading())
6614 MCAuto<DataArrayMedInt> miNumCells=DataArrayMedInt::New();
6615 miNumCells->alloc(nbOfElt,1);
6616 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miNumCells->getPointer()));
6617 numCells = FromMedIntArray<mcIdType>( miNumCells );
6620 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6623 if(!mrs || mrs->isCellNameFieldReading())
6625 namesCells=DataArrayAsciiChar::New();
6626 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6627 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6628 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6633 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6635 setName(strm->getName());
6636 setDescription(strm->getDescription());
6637 setUnivName(strm->getUnivName());
6638 setIteration(strm->getIteration());
6639 setOrder(strm->getOrder());
6640 setTimeValue(strm->getTime());
6641 setTimeUnit(strm->getTimeUnit());
6642 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6643 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6644 mcIdType nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6647 if(!mrs || mrs->isNodeFamilyFieldReading())
6649 mcIdType nbNodes(getNumberOfNodes());
6651 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6652 MCAuto<DataArrayMedInt> miFamNodes=DataArrayMedInt::New();
6653 miFamNodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6654 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...
6655 miFamNodes->fillWithZero();
6656 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miFamNodes->getPointer()));
6657 _fam_nodes = FromMedIntArray<mcIdType>( miFamNodes );
6660 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6663 if(!mrs || mrs->isNodeNumFieldReading())
6665 MCAuto<DataArrayMedInt> miNumNodes=DataArrayMedInt::New();
6666 miNumNodes->alloc(nbOfElt,1);
6667 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miNumNodes->getPointer()));
6668 _num_nodes = FromMedIntArray<mcIdType>( miNumNodes );
6671 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6674 if(!mrs || mrs->isNodeNameFieldReading())
6676 _names_nodes=DataArrayAsciiChar::New();
6677 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6678 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6679 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6682 int meshDim(getStructuredMesh()->getMeshDimension());
6683 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6685 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6688 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6690 int meshDim(getStructuredMesh()->getMeshDimension());
6691 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6693 if((const DataArrayIdType *)_fam_cells)
6694 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_fam_cells->getNumberOfTuples()),ToMedIntArray(_fam_cells)->getConstPointer()));
6695 if((const DataArrayIdType *)_fam_faces)
6696 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_fam_faces->getNumberOfTuples()),ToMedIntArray(_fam_faces)->getConstPointer()));
6697 if((const DataArrayIdType *)_fam_nodes)
6698 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_fam_nodes->getNumberOfTuples()),ToMedIntArray(_fam_nodes)->getConstPointer()));
6699 if((const DataArrayIdType *)_num_cells)
6700 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_num_cells->getNumberOfTuples()),ToMedIntArray(_num_cells)->getConstPointer()));
6701 if((const DataArrayIdType *)_num_faces)
6702 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_num_faces->getNumberOfTuples()),ToMedIntArray(_num_faces)->getConstPointer()));
6703 if((const DataArrayIdType *)_num_nodes)
6704 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_num_nodes->getNumberOfTuples()),ToMedIntArray(_num_nodes)->getConstPointer()));
6705 if((const DataArrayAsciiChar *)_names_cells)
6707 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6709 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6710 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6711 throw INTERP_KERNEL::Exception(oss.str().c_str());
6713 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_names_cells->getNumberOfTuples()),_names_cells->getConstPointer()));
6715 if((const DataArrayAsciiChar *)_names_faces)
6717 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6719 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6720 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6721 throw INTERP_KERNEL::Exception(oss.str().c_str());
6723 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_names_faces->getNumberOfTuples()),_names_faces->getConstPointer()));
6725 if((const DataArrayAsciiChar *)_names_nodes)
6727 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6729 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6730 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6731 throw INTERP_KERNEL::Exception(oss.str().c_str());
6733 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_names_nodes->getNumberOfTuples()),_names_nodes->getConstPointer()));
6736 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6740 * Returns an empty instance of MEDFileCMesh.
6741 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6742 * mesh using decrRef() as it is no more needed.
6744 MEDFileCMesh *MEDFileCMesh::New()
6746 return new MEDFileCMesh;
6750 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6751 * file. The first mesh in the file is loaded.
6752 * \param [in] fileName - the name of MED file to read.
6753 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6754 * mesh using decrRef() as it is no more needed.
6755 * \throw If the file is not readable.
6756 * \throw If there is no meshes in the file.
6757 * \throw If the mesh in the file is not a Cartesian one.
6759 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6761 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6762 return New(fid,mrs);
6765 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6767 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6771 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6772 * file. The mesh to load is specified by its name and numbers of a time step and an
6774 * \param [in] fileName - the name of MED file to read.
6775 * \param [in] mName - the name of the mesh to read.
6776 * \param [in] dt - the number of a time step.
6777 * \param [in] it - the number of an iteration.
6778 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6779 * mesh using decrRef() as it is no more needed.
6780 * \throw If the file is not readable.
6781 * \throw If there is no mesh with given attributes in the file.
6782 * \throw If the mesh in the file is not a Cartesian one.
6784 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6786 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6787 return New(fid,mName,dt,it,mrs);
6790 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6792 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6795 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6797 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6800 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6802 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6803 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6808 * Returns the dimension on cells in \a this mesh.
6809 * \return int - the mesh dimension.
6810 * \throw If there are no cells in this mesh.
6812 int MEDFileCMesh::getMeshDimension() const
6814 if(!((const MEDCouplingCMesh*)_cmesh))
6815 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6816 return _cmesh->getMeshDimension();
6820 * Returns the dimension on nodes in \a this mesh.
6821 * \return int - the space dimension.
6822 * \throw If there are no cells in this mesh.
6824 int MEDFileCMesh::getSpaceDimension() const
6826 if(!((const MEDCouplingCMesh*)_cmesh))
6827 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6828 return _cmesh->getSpaceDimension();
6832 * Returns a string describing \a this mesh.
6833 * \return std::string - the mesh information string.
6835 std::string MEDFileCMesh::simpleRepr() const
6837 return MEDFileStructuredMesh::simpleRepr();
6841 * Returns a full textual description of \a this mesh.
6842 * \return std::string - the string holding the mesh description.
6844 std::string MEDFileCMesh::advancedRepr() const
6846 return simpleRepr();
6849 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6851 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6855 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6857 return new MEDFileCMesh;
6860 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6862 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6863 ret->deepCpyEquivalences(*this);
6864 if((const MEDCouplingCMesh*)_cmesh)
6865 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6866 ret->deepCpyAttributes();
6871 * Checks if \a this and another mesh are equal.
6872 * \param [in] other - the mesh to compare with.
6873 * \param [in] eps - a precision used to compare real values.
6874 * \param [in,out] what - the string returning description of unequal data.
6875 * \return bool - \c true if the meshes are equal, \c false, else.
6877 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6879 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6881 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6884 what="Mesh types differ ! This is cartesian and other is NOT !";
6887 clearNonDiscrAttributes();
6888 otherC->clearNonDiscrAttributes();
6889 const MEDCouplingCMesh *coo1=_cmesh;
6890 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6891 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6893 what="Mismatch of cartesian meshes ! One is defined and not other !";
6898 bool ret=coo1->isEqual(coo2,eps);
6901 what="cartesian meshes differ !";
6909 * Clears redundant attributes of incorporated data arrays.
6911 void MEDFileCMesh::clearNonDiscrAttributes() const
6913 MEDFileStructuredMesh::clearNonDiscrAttributes();
6914 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6917 MEDFileCMesh::MEDFileCMesh()
6921 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6924 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6926 catch(INTERP_KERNEL::Exception& e)
6931 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6933 MEDCoupling::MEDCouplingMeshType meshType;
6936 MEDCoupling::MEDCouplingAxisType axType;
6937 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6938 if(meshType!=CARTESIAN)
6940 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6941 throw INTERP_KERNEL::Exception(oss.str().c_str());
6943 MEDFileCMeshL2 loaderl2;
6944 loaderl2.loadAll(fid,mid,mName,dt,it);
6945 setAxisType(axType);
6946 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6949 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6953 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6954 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6956 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6958 synchronizeTinyInfoOnLeaves();
6962 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6964 synchronizeTinyInfoOnLeaves();
6969 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6970 * \param [in] m - the new MEDCouplingCMesh to refer to.
6971 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6974 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6976 dealWithTinyInfo(m);
6982 MEDFileMesh *MEDFileCMesh::cartesianize() const
6984 if(getAxisType()==AX_CART)
6987 return const_cast<MEDFileCMesh *>(this);
6991 const MEDCouplingCMesh *cmesh(getMesh());
6993 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6994 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6995 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6996 clmesh->setCoords(coords);
6997 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6998 ret->MEDFileStructuredMesh::operator=(*this);
6999 ret->setMesh(clmesh);
7000 ret->setAxisType(AX_CART);
7005 void MEDFileCMesh::writeMeshLL(med_idt fid) const
7007 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7008 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7009 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7010 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7011 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7012 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7013 int spaceDim(_cmesh->getSpaceDimension());
7014 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7015 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7016 for(int i=0;i<spaceDim;i++)
7018 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
7020 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7021 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
7022 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
7024 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7026 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7027 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
7028 for(int i=0;i<spaceDim;i++)
7030 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
7031 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,ToMedInt(da->getNumberOfTuples()),da->getConstPointer()));
7034 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7035 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7038 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
7040 const MEDCouplingCMesh *cmesh=_cmesh;
7043 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
7044 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
7045 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
7046 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
7049 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
7051 return new MEDFileCurveLinearMesh;
7054 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
7056 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
7059 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
7061 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7062 return New(fid,mrs);
7065 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7067 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7068 return New(fid,mName,dt,it,mrs);
7071 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7073 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
7076 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
7078 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
7081 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
7083 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
7084 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
7088 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
7090 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7094 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
7096 return new MEDFileCurveLinearMesh;
7099 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
7101 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7102 ret->deepCpyEquivalences(*this);
7103 if((const MEDCouplingCurveLinearMesh*)_clmesh)
7104 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
7105 ret->deepCpyAttributes();
7109 int MEDFileCurveLinearMesh::getMeshDimension() const
7111 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7112 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
7113 return _clmesh->getMeshDimension();
7116 std::string MEDFileCurveLinearMesh::simpleRepr() const
7118 return MEDFileStructuredMesh::simpleRepr();
7121 std::string MEDFileCurveLinearMesh::advancedRepr() const
7123 return simpleRepr();
7126 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7128 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7130 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
7133 what="Mesh types differ ! This is curve linear and other is NOT !";
7136 clearNonDiscrAttributes();
7137 otherC->clearNonDiscrAttributes();
7138 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
7139 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
7140 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7142 what="Mismatch of curve linear meshes ! One is defined and not other !";
7147 bool ret=coo1->isEqual(coo2,eps);
7150 what="curve linear meshes differ !";
7157 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
7159 MEDFileStructuredMesh::clearNonDiscrAttributes();
7160 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
7163 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
7165 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
7168 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
7169 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
7170 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
7171 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
7174 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
7176 synchronizeTinyInfoOnLeaves();
7180 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
7182 dealWithTinyInfo(m);
7188 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
7190 if(getAxisType()==AX_CART)
7193 return const_cast<MEDFileCurveLinearMesh *>(this);
7197 const MEDCouplingCurveLinearMesh *mesh(getMesh());
7199 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7200 const DataArrayDouble *coords(mesh->getCoords());
7202 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
7203 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7204 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
7205 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7206 mesh2->setCoords(coordsCart);
7207 ret->setMesh(mesh2);
7208 ret->setAxisType(AX_CART);
7213 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7215 synchronizeTinyInfoOnLeaves();
7219 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7223 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7226 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7228 catch(INTERP_KERNEL::Exception& e)
7233 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7235 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7236 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7237 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7238 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7239 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7240 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7241 int spaceDim=_clmesh->getSpaceDimension();
7242 int meshDim=_clmesh->getMeshDimension();
7243 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7244 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7245 const DataArrayDouble *coords=_clmesh->getCoords();
7247 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7248 for(int i=0;i<spaceDim;i++)
7250 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7252 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7253 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
7254 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
7256 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7258 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7259 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7260 std::vector<mcIdType> nodeGridSt=_clmesh->getNodeGridStructure();
7261 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,ToMedIntArray(nodeGridSt)->getConstPointer()));
7263 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,ToMedInt(coords->getNumberOfTuples()),coords->begin()));
7265 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7266 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7269 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7271 MEDCoupling::MEDCouplingMeshType meshType;
7274 MEDCoupling::MEDCouplingAxisType axType;
7275 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7276 setAxisType(axType);
7277 if(meshType!=CURVE_LINEAR)
7279 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7280 throw INTERP_KERNEL::Exception(oss.str().c_str());
7282 MEDFileCLMeshL2 loaderl2;
7283 loaderl2.loadAll(fid,mid,mName,dt,it);
7284 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7287 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7290 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7292 return new MEDFileMeshMultiTS;
7295 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7297 return new MEDFileMeshMultiTS(fid);
7300 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7302 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7306 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7308 return new MEDFileMeshMultiTS(fid,mName);
7311 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7313 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7314 return New(fid,mName);
7317 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7319 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7320 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7322 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7323 if((const MEDFileMesh *)*it)
7324 meshOneTs[i]=(*it)->deepCopy();
7325 ret->_mesh_one_ts=meshOneTs;
7329 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7331 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7334 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7336 std::vector<const BigMemoryObject *> ret;
7337 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7338 ret.push_back((const MEDFileMesh *)*it);
7342 std::string MEDFileMeshMultiTS::getName() const
7344 if(_mesh_one_ts.empty())
7345 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7346 return _mesh_one_ts[0]->getName();
7349 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7351 std::string oldName(getName());
7352 std::vector< std::pair<std::string,std::string> > v(1);
7353 v[0].first=oldName; v[0].second=newMeshName;
7357 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7360 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7362 MEDFileMesh *cur(*it);
7364 ret=cur->changeNames(modifTab) || ret;
7369 void MEDFileMeshMultiTS::cartesianizeMe()
7371 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7373 MEDFileMesh *cur(*it);
7376 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7382 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7384 if(_mesh_one_ts.empty())
7385 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7386 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7389 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7392 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7393 _mesh_one_ts.resize(1);
7394 mesh1TimeStep->incrRef();
7395 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7396 _mesh_one_ts[0]=mesh1TimeStep;
7399 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7401 if ( MEDFileMesh* m = getOneTimeStep() )
7402 return m->getJoints();
7407 * \brief Set Joints that are common to all time-stamps
7409 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7411 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7413 (*it)->setJoints( joints );
7417 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7419 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7420 if((*it).isNotNull())
7421 if((*it)->presenceOfStructureElements())
7426 void MEDFileMeshMultiTS::killStructureElements()
7428 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7429 if((*it).isNotNull())
7430 (*it)->killStructureElements();
7433 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7435 MEDFileJoints *joints(getJoints());
7436 bool jointsWritten(false);
7438 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7440 if ( jointsWritten )
7441 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7443 jointsWritten = true;
7445 (*it)->copyOptionsFrom(*this);
7446 (*it)->writeLL(fid);
7449 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7452 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7454 MEDFileJoints *joints(0);
7455 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7457 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7458 joints = getOneTimeStep()->getJoints();
7460 _mesh_one_ts.clear(); //for the moment to be improved
7461 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7464 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7468 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7471 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7474 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7475 throw INTERP_KERNEL::Exception(oss.str().c_str());
7478 MEDCoupling::MEDCouplingMeshType meshType;
7480 MEDCoupling::MEDCouplingAxisType dummy3;
7481 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7482 loadFromFile(fid,ms.front());
7484 catch(INTERP_KERNEL::Exception& e)
7489 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7492 loadFromFile(fid,mName);
7494 catch(INTERP_KERNEL::Exception& e)
7499 MEDFileMeshes *MEDFileMeshes::New()
7501 return new MEDFileMeshes;
7504 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7506 return new MEDFileMeshes(fid);
7509 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7511 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7515 void MEDFileMeshes::writeLL(med_idt fid) const
7517 checkConsistencyLight();
7518 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7520 (*it)->copyOptionsFrom(*this);
7521 (*it)->writeLL(fid);
7525 // MEDFileMeshes::writ checkConsistencyLight();
7527 int MEDFileMeshes::getNumberOfMeshes() const
7529 return (int)_meshes.size();
7532 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7534 return new MEDFileMeshesIterator(this);
7537 /** Return a borrowed reference (caller is not responsible) */
7538 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7540 if(i<0 || i>=(int)_meshes.size())
7542 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7543 throw INTERP_KERNEL::Exception(oss.str().c_str());
7545 return _meshes[i]->getOneTimeStep();
7548 /** Return a borrowed reference (caller is not responsible) */
7549 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7551 std::vector<std::string> ms=getMeshesNames();
7552 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7555 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7556 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7557 throw INTERP_KERNEL::Exception(oss.str().c_str());
7559 return getMeshAtPos((int)std::distance(ms.begin(),it));
7562 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7564 std::vector<std::string> ret(_meshes.size());
7566 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7568 const MEDFileMeshMultiTS *f=(*it);
7571 ret[i]=f->getName();
7575 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7576 throw INTERP_KERNEL::Exception(oss.str().c_str());
7582 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7585 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7587 MEDFileMeshMultiTS *cur(*it);
7589 ret=cur->changeNames(modifTab) || ret;
7594 void MEDFileMeshes::cartesianizeMe()
7596 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7598 MEDFileMeshMultiTS *cur(*it);
7600 cur->cartesianizeMe();
7604 void MEDFileMeshes::resize(int newSize)
7606 _meshes.resize(newSize);
7609 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7612 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7613 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7614 elt->setOneTimeStep(mesh);
7615 _meshes.push_back(elt);
7618 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7621 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7622 if(i>=(int)_meshes.size())
7623 _meshes.resize(i+1);
7624 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7625 elt->setOneTimeStep(mesh);
7629 void MEDFileMeshes::destroyMeshAtPos(int i)
7631 if(i<0 || i>=(int)_meshes.size())
7633 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7634 throw INTERP_KERNEL::Exception(oss.str().c_str());
7636 _meshes.erase(_meshes.begin()+i);
7639 void MEDFileMeshes::loadFromFile(med_idt fid)
7641 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7643 _meshes.resize(ms.size());
7644 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7645 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7648 MEDFileMeshes::MEDFileMeshes()
7652 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7657 catch(INTERP_KERNEL::Exception& /*e*/)
7661 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7663 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7665 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7666 if((const MEDFileMeshMultiTS *)*it)
7667 meshes[i]=(*it)->deepCopy();
7668 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7669 ret->_meshes=meshes;
7673 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7675 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7678 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7680 std::vector<const BigMemoryObject *> ret;
7681 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7682 ret.push_back((const MEDFileMeshMultiTS *)*it);
7686 std::string MEDFileMeshes::simpleRepr() const
7688 std::ostringstream oss;
7689 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7690 simpleReprWithoutHeader(oss);
7694 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7696 int nbOfMeshes=getNumberOfMeshes();
7697 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7698 std::vector<std::string> mns=getMeshesNames();
7699 for(int i=0;i<nbOfMeshes;i++)
7700 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7703 void MEDFileMeshes::checkConsistencyLight() const
7705 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7707 std::set<std::string> s;
7708 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7710 const MEDFileMeshMultiTS *elt=(*it);
7713 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7714 throw INTERP_KERNEL::Exception(oss.str().c_str());
7716 std::size_t sz=s.size();
7717 s.insert(std::string((*it)->getName()));
7720 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7721 throw INTERP_KERNEL::Exception(oss.str().c_str());
7726 bool MEDFileMeshes::presenceOfStructureElements() const
7728 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7729 if((*it).isNotNull())
7730 if((*it)->presenceOfStructureElements())
7735 void MEDFileMeshes::killStructureElements()
7737 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7738 if((*it).isNotNull())
7739 (*it)->killStructureElements();
7742 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7747 _nb_iter=ms->getNumberOfMeshes();
7751 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7755 MEDFileMesh *MEDFileMeshesIterator::nextt()
7757 if(_iter_id<_nb_iter)
7759 MEDFileMeshes *ms(_ms);
7761 return ms->getMeshAtPos(_iter_id++);
7769 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7771 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7772 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7774 if(geoType==MED_NO_GEOTYPE)
7775 return INTERP_KERNEL::NORM_ERROR;
7776 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7777 throw INTERP_KERNEL::Exception(oss.str());
7779 return typmai2[std::distance(typmai,pos)];
7782 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7790 case MED_NODE_ELEMENT:
7794 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7795 throw INTERP_KERNEL::Exception(oss.str());