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);
2482 * This method is an helper to load only consecutive nodes chunk of data of MED file pointed by \a fileName.
2483 * Consecutive chunk is specified classicaly by start (included) stop (excluded) format with \a startNodeId and \a stopNodeId respectively.
2484 * This method returns 5 elements.
2486 * \param [in] fileName - Name of file nodes to be read of.
2487 * \param [in] mName - Name of the mesh inside file pointed be \a fileName nodes to be read of.
2488 * \param [in] dt - Time iteration inside file pointed be \a fileName nodes to be read of.
2489 * \param [in] it - Time order inside file pointed be \a fileName nodes to be read of.
2490 * \param [in] infosOnCompo - Components info of nodes to be read of. The size of string vector should be equal to space dimension of mesh to be read.
2491 * \param [in] startNodeId - Start Node Id (included) of chunk of data to be read
2492 * \param [in] stopNodeId - Start Node Id (included) of chunk of data to be read
2493 * \param [out] coords - output coordinates of requested chunk (DataArrayDouble)
2494 * \param [out] partCoords - output PartDefinition object of chunk
2495 * \param [out] famCoords - output family id field of requested chunk (DataArrayIdType)
2496 * \param [out] numCoords - output num id field of requested chunk (DataArrayIdType)
2497 * \param [out] nameCoords - output names on nodes of requested chunk (DataArrayAsciiChar)
2499 * \sa MEDLoaderUMesh::LoadPartOf
2501 void MEDFileUMesh::LoadPartCoords(const std::string& fileName, const std::string& mName, int dt, int it, const std::vector<std::string>& infosOnComp, mcIdType startNodeId, mcIdType stopNodeId,
2502 MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<DataArrayIdType>& famCoords, MCAuto<DataArrayIdType>& numCoords, MCAuto<DataArrayAsciiChar>& nameCoords)
2504 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2505 MEDFileUMeshL2::LoadPartCoords(fid,infosOnComp,mName,dt,it,startNodeId,stopNodeId,coords,partCoords,famCoords,numCoords,nameCoords);
2508 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2510 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2511 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2515 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2517 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2518 ret.push_back((const DataArrayDouble*)_coords);
2519 ret.push_back((const DataArrayIdType *)_fam_coords);
2520 ret.push_back((const DataArrayIdType *)_num_coords);
2521 ret.push_back((const DataArrayIdType *)_global_num_coords);
2522 ret.push_back((const DataArrayIdType *)_rev_num_coords);
2523 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2524 ret.push_back((const PartDefinition *)_part_coords);
2525 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2526 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2527 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2528 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2532 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2534 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2538 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2540 return new MEDFileUMesh;
2543 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2545 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2546 ret->deepCpyEquivalences(*this);
2547 if(_coords.isNotNull())
2548 ret->_coords=_coords->deepCopy();
2549 if(_fam_coords.isNotNull())
2550 ret->_fam_coords=_fam_coords->deepCopy();
2551 if(_num_coords.isNotNull())
2552 ret->_num_coords=_num_coords->deepCopy();
2553 if(_global_num_coords.isNotNull())
2554 ret->_global_num_coords=_global_num_coords->deepCopy();
2555 if(_rev_num_coords.isNotNull())
2556 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2557 if(_name_coords.isNotNull())
2558 ret->_name_coords=_name_coords->deepCopy();
2560 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2562 if((const MEDFileUMeshSplitL1 *)(*it))
2563 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2565 if((const PartDefinition*)_part_coords)
2566 ret->_part_coords=_part_coords->deepCopy();
2571 * Checks if \a this and another mesh are equal.
2572 * \param [in] other - the mesh to compare with.
2573 * \param [in] eps - a precision used to compare real values.
2574 * \param [in,out] what - the string returning description of unequal data.
2575 * \return bool - \c true if the meshes are equal, \c false, else.
2577 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2579 if(!MEDFileMesh::isEqual(other,eps,what))
2581 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2584 what="Mesh types differ ! This is unstructured and other is NOT !";
2587 clearNonDiscrAttributes();
2588 otherC->clearNonDiscrAttributes();
2589 const DataArrayDouble *coo1=_coords;
2590 const DataArrayDouble *coo2=otherC->_coords;
2591 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2593 what="Mismatch of coordinates ! One is defined and not other !";
2598 bool ret=coo1->isEqual(*coo2,eps);
2601 what="Coords differ !";
2606 const DataArrayIdType *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2607 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2609 what="Mismatch of families arr on nodes ! One is defined and not other !";
2614 bool ret=famc1->isEqual(*famc2);
2617 what="Families arr on node differ !";
2623 const DataArrayIdType *numc1(_num_coords),*numc2(otherC->_num_coords);
2624 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2626 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2631 bool ret=numc1->isEqual(*numc2);
2634 what="Numbering arr on node differ !";
2640 const DataArrayIdType *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2641 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2643 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2648 bool ret=gnumc1->isEqual(*gnumc2);
2651 what="Global numbering arr on node differ !";
2657 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2658 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2660 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2665 bool ret=namec1->isEqual(*namec2);
2668 what="Names arr on node differ !";
2673 if(_ms.size()!=otherC->_ms.size())
2675 what="Number of levels differs !";
2678 std::size_t sz=_ms.size();
2679 for(std::size_t i=0;i<sz;i++)
2681 const MEDFileUMeshSplitL1 *s1=_ms[i];
2682 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2683 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2685 what="Mismatch of presence of sub levels !";
2690 bool ret=s1->isEqual(s2,eps,what);
2695 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2698 if((!pd0 && pd1) || (pd0 && !pd1))
2700 what=std::string("node part def is defined only for one among this or other !");
2703 return pd0->isEqual(pd1,what);
2707 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2708 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2709 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2710 * \throw if internal family array is inconsistent
2711 * \sa checkSMESHConsistency()
2713 void MEDFileUMesh::checkConsistency() const
2715 if(!_coords || !_coords->isAllocated())
2718 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2720 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2721 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2722 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2726 mcIdType nbCoo = _coords->getNumberOfTuples();
2727 if (_fam_coords.isNotNull())
2728 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2729 if (_num_coords.isNotNull())
2731 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2733 mcIdType maxValue=_num_coords->getMaxValue(pos);
2734 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2735 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2737 if (_global_num_coords.isNotNull())
2739 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2741 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2742 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2743 if (_num_coords && !_num_coords->hasUniqueValues())
2744 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2746 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2747 // Now sub part check:
2748 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2749 it != _ms.end(); it++)
2750 (*it)->checkConsistency();
2755 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2756 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2757 * entities as it likes), or non overlapping between all sub-levels.
2758 * \throw if the condition above is not respected
2760 void MEDFileUMesh::checkSMESHConsistency() const
2763 // For all sub-levels, numbering is either always null or with void intersection:
2766 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2767 std::vector< const DataArrayIdType * > v;
2768 bool voidOrNot = ((*it)->_num == 0);
2769 for (it++; it != _ms.end(); it++)
2770 if( ((*it)->_num == 0) != voidOrNot )
2771 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2772 else if (!voidOrNot)
2773 v.push_back((*it)->_num);
2776 // don't forget the 1st one:
2777 v.push_back(_ms[0]->_num);
2778 MCAuto<DataArrayIdType> inter = DataArrayIdType::BuildIntersection(v);
2779 if (inter->getNumberOfTuples())
2780 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2786 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2787 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2789 void MEDFileUMesh::clearNodeAndCellNumbers()
2791 _num_coords.nullify();
2792 _rev_num_coords.nullify();
2793 _global_num_coords.nullify();
2794 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2796 (*it)->_num.nullify();
2797 (*it)->_rev_num.nullify();
2798 (*it)->_global_num.nullify();
2803 * Clears redundant attributes of incorporated data arrays.
2805 void MEDFileUMesh::clearNonDiscrAttributes() const
2807 MEDFileMesh::clearNonDiscrAttributes();
2808 if(_coords.isNotNull())
2809 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2810 if(_fam_coords.isNotNull())
2811 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2812 if(_num_coords.isNotNull())
2813 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2814 if(_name_coords.isNotNull())
2815 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2816 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2818 if((*it).isNotNull())
2819 (*it)->clearNonDiscrAttributes();
2823 void MEDFileUMesh::setName(const std::string& name)
2825 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2826 if((*it).isNotNull())
2827 (*it)->setName(name);
2828 MEDFileMesh::setName(name);
2831 MEDFileUMesh::MEDFileUMesh()
2835 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2838 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2840 catch(INTERP_KERNEL::Exception& e)
2846 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2847 * See MEDFileUMesh::LoadPartOf for detailed description.
2851 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)
2853 MEDFileUMeshL2 loaderl2;
2854 MEDCoupling::MEDCouplingMeshType meshType;
2857 MEDCoupling::MEDCouplingAxisType dummy3;
2858 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2859 if(meshType!=UNSTRUCTURED)
2861 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2862 throw INTERP_KERNEL::Exception(oss.str().c_str());
2864 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2865 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2869 * \brief Write joints in a file
2871 void MEDFileMesh::writeJoints(med_idt fid) const
2873 if ( _joints.isNotNull() )
2874 _joints->writeLL(fid);
2878 * \brief Load joints in a file or use provided ones
2880 //================================================================================
2882 * \brief Load joints in a file or use provided ones
2883 * \param [in] fid - MED file descriptor
2884 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2885 * Usually this joints are those just read by another iteration
2886 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2888 //================================================================================
2890 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2892 if ( toUseInstedOfReading )
2893 setJoints( toUseInstedOfReading );
2895 _joints = MEDFileJoints::New( fid, _name );
2898 void MEDFileMesh::loadEquivalences(med_idt fid)
2900 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2902 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2905 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2907 const MEDFileEquivalences *equiv(other._equiv);
2909 _equiv=equiv->deepCopy(this);
2912 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2914 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2915 if(!thisEq && !otherEq)
2917 if(thisEq && otherEq)
2918 return thisEq->isEqual(otherEq,what);
2921 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2926 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2928 const MEDFileEquivalences *equiv(_equiv);
2931 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2932 _equiv->getRepr(oss);
2935 void MEDFileMesh::checkCartesian() const
2937 if(getAxisType()!=AX_CART)
2939 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()) << ").";
2940 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2941 oss << " - call setAxisType(AX_CART)" << std::endl;
2942 oss << " - call cartesianize()";
2943 throw INTERP_KERNEL::Exception(oss.str().c_str());
2948 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2950 int MEDFileMesh::getNumberOfJoints() const
2952 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2956 * \brief Return joints with all adjacent mesh domains
2958 MEDFileJoints * MEDFileMesh::getJoints() const
2960 return const_cast<MEDFileJoints*>(& (*_joints));
2963 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2965 if ( joints != _joints )
2974 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2976 * \sa loadPartUMeshFromFile
2978 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2980 MEDFileUMeshL2 loaderl2;
2981 MEDCoupling::MEDCouplingMeshType meshType;
2984 MEDCoupling::MEDCouplingAxisType axType;
2985 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2986 setAxisType(axType);
2987 if(meshType!=UNSTRUCTURED)
2989 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2990 throw INTERP_KERNEL::Exception(oss.str().c_str());
2992 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2993 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2994 // Structure element part...
2995 med_int nModels(-1);
2997 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2998 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
3002 _elt_str.resize(nModels);
3003 for(int i=0;i<nModels;i++)
3004 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
3007 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
3009 int lev=loaderl2.getNumberOfLevels();
3011 for(int i=0;i<lev;i++)
3013 if(!loaderl2.emptyLev(i))
3014 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
3018 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
3020 setName(loaderl2.getName());
3021 setDescription(loaderl2.getDescription());
3022 setUnivName(loaderl2.getUnivName());
3023 setIteration(loaderl2.getIteration());
3024 setOrder(loaderl2.getOrder());
3025 setTimeValue(loaderl2.getTime());
3026 setTimeUnit(loaderl2.getTimeUnit());
3027 _coords=loaderl2.getCoords();
3028 if(!mrs || mrs->isNodeFamilyFieldReading())
3029 _fam_coords=loaderl2.getCoordsFamily();
3030 if(!mrs || mrs->isNodeNumFieldReading())
3031 _num_coords=loaderl2.getCoordsNum();
3032 if(!mrs || mrs->isNodeNameFieldReading())
3033 _name_coords=loaderl2.getCoordsName();
3034 if(!mrs || mrs->isGlobalNodeNumFieldReading())
3035 _global_num_coords=loaderl2.getCoordsGlobalNum();
3036 _part_coords=loaderl2.getPartDefOfCoo();
3040 MEDFileUMesh::~MEDFileUMesh()
3044 void MEDFileUMesh::writeMeshLL(med_idt fid) const
3046 const DataArrayDouble *coo=_coords;
3047 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3048 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3049 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3050 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3051 int spaceDim=(int)(coo?coo->getNumberOfComponents():0);
3054 mdim=getMeshDimension();
3055 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3056 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3057 for(int i=0;i<spaceDim;i++)
3059 std::string info=coo->getInfoOnComponent(i);
3061 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3062 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
3063 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
3065 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
3067 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
3068 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
3069 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
3070 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3071 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3072 (*it)->write(fid,meshName,mdim);
3073 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
3077 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
3078 * \return std::vector<int> - a sequence of the relative dimensions.
3080 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
3082 std::vector<int> ret;
3084 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3085 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3092 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
3093 * \return std::vector<int> - a sequence of the relative dimensions.
3095 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
3097 std::vector<int> ret0=getNonEmptyLevels();
3098 if((const DataArrayDouble *) _coords)
3100 std::vector<int> ret(ret0.size()+1);
3102 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3108 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
3110 std::vector<int> ret;
3111 const DataArrayIdType *famCoo(_fam_coords);
3115 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3117 const MEDFileUMeshSplitL1 *cur(*it);
3119 if(cur->getFamilyField())
3125 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3127 std::vector<int> ret;
3128 if(_num_coords.isNotNull())
3131 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3133 const MEDFileUMeshSplitL1 *cur(*it);
3135 if(cur->getNumberField())
3141 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3143 std::vector<int> ret;
3144 const DataArrayAsciiChar *nameCoo(_name_coords);
3148 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3150 const MEDFileUMeshSplitL1 *cur(*it);
3152 if(cur->getNameField())
3159 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3160 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3161 * \param [in] fams - the name of the family of interest.
3162 * \return std::vector<int> - a sequence of the relative dimensions.
3164 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3166 std::vector<mcIdType> ret;
3167 std::vector<int> levs(getNonEmptyLevels());
3168 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3169 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3170 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3176 * Returns all relative mesh levels (including nodes) where given families are defined.
3177 * \param [in] fams - the names of the families of interest.
3178 * \return std::vector<int> - a sequence of the relative dimensions.
3180 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3182 std::vector<mcIdType> ret0(getFamsNonEmptyLevels(fams));
3183 const DataArrayIdType *famCoords(_fam_coords);
3186 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3187 if(famCoords->presenceOfValue(famIds))
3189 std::vector<mcIdType> ret(ret0.size()+1);
3191 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3198 mcIdType MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3200 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3201 if((const DataArrayIdType *)_fam_coords)
3203 mcIdType val=_fam_coords->getMaxValue(tmp);
3204 ret=std::max(ret,std::abs(val));
3206 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3208 if((const MEDFileUMeshSplitL1 *)(*it))
3210 const DataArrayIdType *da=(*it)->getFamilyField();
3213 mcIdType val=da->getMaxValue(tmp);
3214 ret=std::max(ret,std::abs(val));
3221 mcIdType MEDFileUMesh::getMaxFamilyIdInArrays() const
3223 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3224 if((const DataArrayIdType *)_fam_coords)
3226 mcIdType val=_fam_coords->getMaxValue(tmp);
3227 ret=std::max(ret,val);
3229 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3231 if((const MEDFileUMeshSplitL1 *)(*it))
3233 const DataArrayIdType *da=(*it)->getFamilyField();
3236 mcIdType val=da->getMaxValue(tmp);
3237 ret=std::max(ret,val);
3244 mcIdType MEDFileUMesh::getMinFamilyIdInArrays() const
3246 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
3247 if((const DataArrayIdType *)_fam_coords)
3249 mcIdType val=_fam_coords->getMinValue(tmp);
3250 ret=std::min(ret,val);
3252 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3254 if((const MEDFileUMeshSplitL1 *)(*it))
3256 const DataArrayIdType *da=(*it)->getFamilyField();
3259 mcIdType val=da->getMinValue(tmp);
3260 ret=std::min(ret,val);
3268 * Returns the dimension on cells in \a this mesh.
3269 * \return int - the mesh dimension.
3270 * \throw If there are no cells in this mesh.
3272 int MEDFileUMesh::getMeshDimension() const
3275 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3276 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3277 return (*it)->getMeshDimension()+lev;
3278 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3282 * Returns the space dimension of \a this mesh that is equal to number of components in
3283 * the node coordinates array.
3284 * \return int - the space dimension of \a this mesh.
3285 * \throw If the node coordinates array is not available.
3287 int MEDFileUMesh::getSpaceDimension() const
3289 const DataArrayDouble *coo=_coords;
3291 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3292 return (int)coo->getNumberOfComponents();
3296 * Returns a string describing \a this mesh.
3297 * \return std::string - the mesh information string.
3299 std::string MEDFileUMesh::simpleRepr() const
3301 std::ostringstream oss;
3302 oss << MEDFileMesh::simpleRepr();
3303 const DataArrayDouble *coo=_coords;
3304 oss << "- The dimension of the space is ";
3305 static const char MSG1[]= "*** NO COORDS SET ***";
3306 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3308 oss << _coords->getNumberOfComponents() << std::endl;
3310 oss << MSG1 << std::endl;
3311 oss << "- Type of the mesh : UNSTRUCTURED\n";
3312 oss << "- Number of nodes : ";
3314 oss << _coords->getNumberOfTuples() << std::endl;
3316 oss << MSG1 << std::endl;
3317 std::size_t nbOfLev=_ms.size();
3318 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3319 for(std::size_t i=0;i<nbOfLev;i++)
3321 const MEDFileUMeshSplitL1 *lev=_ms[i];
3322 oss << " - Level #" << -((int) i) << " has dimension : ";
3325 oss << lev->getMeshDimension() << std::endl;
3326 lev->simpleRepr(oss);
3329 oss << MSG2 << std::endl;
3331 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3334 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3335 oss << "- Names of coordinates :" << std::endl;
3336 std::vector<std::string> vars=coo->getVarsOnComponent();
3337 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3338 oss << std::endl << "- Units of coordinates : " << std::endl;
3339 std::vector<std::string> units=coo->getUnitsOnComponent();
3340 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3342 oss << std::endl << std::endl;
3344 getEquivalencesRepr(oss);
3349 * Returns a full textual description of \a this mesh.
3350 * \return std::string - the string holding the mesh description.
3352 std::string MEDFileUMesh::advancedRepr() const
3354 return simpleRepr();
3358 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3359 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3360 * \return mcIdType - the number of entities.
3361 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3363 mcIdType MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3365 if(meshDimRelToMaxExt==1)
3367 if(!((const DataArrayDouble *)_coords))
3368 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3369 return _coords->getNumberOfTuples();
3371 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3375 * Returns the family field for mesh entities of a given dimension.
3376 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3377 * \return const DataArrayIdType * - the family field. It is an array of ids of families
3378 * each mesh entity belongs to. It can be \c NULL.
3380 const DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3382 if(meshDimRelToMaxExt==1)
3384 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3385 return l1->getFamilyField();
3388 DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3390 if(meshDimRelToMaxExt==1)
3392 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3393 return l1->getFamilyField();
3397 * Returns the optional numbers of mesh entities of a given dimension.
3398 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3399 * \return const DataArrayIdType * - the array of the entity numbers.
3400 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3402 const DataArrayIdType *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3404 if(meshDimRelToMaxExt==1)
3406 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3407 return l1->getNumberField();
3410 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3412 if(meshDimRelToMaxExt==1)
3413 return _name_coords;
3414 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3415 return l1->getNameField();
3418 MCAuto<DataArrayIdType> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3420 if(meshDimRelToMaxExt!=1)
3421 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3422 return _global_num_coords;
3426 * 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).
3428 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3429 * \param [in] gt - The input geometric type for which the part definition is requested.
3430 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3432 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3434 if(meshDimRelToMaxExt==1)
3435 return _part_coords;
3436 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3437 return l1->getPartDef(gt);
3440 mcIdType MEDFileUMesh::getNumberOfNodes() const
3442 const DataArrayDouble *coo(_coords);
3444 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3445 return coo->getNumberOfTuples();
3448 mcIdType MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3450 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3451 return l1->getNumberOfCells();
3454 bool MEDFileUMesh::hasImplicitPart() const
3459 mcIdType MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3461 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3464 void MEDFileUMesh::releaseImplicitPartIfAny() const
3468 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3470 std::size_t sz(st.getNumberOfItems());
3471 for(std::size_t i=0;i<sz;i++)
3473 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3474 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3475 if(st[i].getPflName().empty())
3476 m->computeNodeIdsAlg(nodesFetched);
3479 const DataArrayIdType *arr(globs->getProfile(st[i].getPflName()));
3480 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3481 m2->computeNodeIdsAlg(nodesFetched);
3486 MEDFileMesh *MEDFileUMesh::cartesianize() const
3488 if(getAxisType()==AX_CART)
3491 return const_cast<MEDFileUMesh *>(this);
3495 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3496 const DataArrayDouble *coords(_coords);
3498 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3499 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3500 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3501 if((const MEDFileUMeshSplitL1 *)(*it))
3502 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3503 ret->_coords=coordsCart;
3504 ret->setAxisType(AX_CART);
3509 bool MEDFileUMesh::presenceOfStructureElements() const
3511 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3512 if((*it).isNotNull())
3517 void MEDFileUMesh::killStructureElements()
3523 * Returns the optional numbers of mesh entities of a given dimension transformed using
3524 * DataArrayIdType::invertArrayN2O2O2N().
3525 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3526 * \return const DataArrayIdType * - the array of the entity numbers transformed using
3527 * DataArrayIdType::invertArrayN2O2O2N().
3528 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3530 const DataArrayIdType *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3532 if(meshDimRelToMaxExt==1)
3534 if(_num_coords.isNull())
3535 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3536 return _rev_num_coords;
3538 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3539 return l1->getRevNumberField();
3543 * Returns a pointer to the node coordinates array of \a this mesh \b without
3544 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3546 DataArrayDouble *MEDFileUMesh::getCoords() const
3549 MCAuto<DataArrayDouble> tmp(_coords);
3550 if((DataArrayDouble *)tmp)
3558 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3559 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3561 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3562 * \param [in] grp - the name of the group whose mesh entities are included in the
3564 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3565 * according to the optional numbers of entities, if available.
3566 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3567 * delete this mesh using decrRef() as it is no more needed.
3568 * \throw If the name of a nonexistent group is specified.
3569 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3571 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3574 synchronizeTinyInfoOnLeaves();
3575 std::vector<std::string> tmp(1);
3577 return getGroups(meshDimRelToMaxExt,tmp,renum);
3581 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3582 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3584 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3585 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3587 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3588 * according to the optional numbers of entities, if available.
3589 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3590 * delete this mesh using decrRef() as it is no more needed.
3591 * \throw If a name of a nonexistent group is present in \a grps.
3592 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3594 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3597 synchronizeTinyInfoOnLeaves();
3598 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3599 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3600 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3601 zeRet->setName(grps[0]);
3602 return zeRet.retn();
3606 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3607 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3609 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3610 * \param [in] fam - the name of the family whose mesh entities are included in the
3612 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3613 * according to the optional numbers of entities, if available.
3614 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3615 * delete this mesh using decrRef() as it is no more needed.
3616 * \throw If a name of a nonexistent family is present in \a grps.
3617 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3619 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3622 synchronizeTinyInfoOnLeaves();
3623 std::vector<std::string> tmp(1);
3625 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3629 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3630 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3632 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3633 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3635 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3636 * according to the optional numbers of entities, if available.
3637 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3638 * delete this mesh using decrRef() as it is no more needed.
3639 * \throw If a name of a nonexistent family is present in \a fams.
3640 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3642 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3645 synchronizeTinyInfoOnLeaves();
3646 if(meshDimRelToMaxExt==1)
3648 MCAuto<DataArrayIdType> arr=getFamiliesArr(1,fams,renum);
3649 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3650 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3654 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3655 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3656 MCAuto<MEDCouplingUMesh> zeRet;
3658 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3660 zeRet=l1->getFamilyPart(0,0,renum);
3661 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3662 zeRet->setName(fams[0]);
3663 return zeRet.retn();
3667 * Returns ids of mesh entities contained in given families of a given dimension.
3668 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3670 * \param [in] fams - the names of the families of interest.
3671 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3672 * returned instead of ids.
3673 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
3674 * numbers, if available and required, of mesh entities of the families. The caller
3675 * is to delete this array using decrRef() as it is no more needed.
3676 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3678 DataArrayIdType *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3680 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3681 if(meshDimRelToMaxExt==1)
3683 if((const DataArrayIdType *)_fam_coords)
3685 MCAuto<DataArrayIdType> da;
3687 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3689 da=_fam_coords->findIdsEqualList(0,0);
3691 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3696 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3698 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3700 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3702 return l1->getFamilyPartArr(0,0,renum);
3706 * Returns a MEDCouplingUMesh of a given relative dimension.
3707 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3708 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3709 * To build a valid MEDCouplingUMesh from the returned one in this case,
3710 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3711 * \param [in] meshDimRelToMax - the relative dimension of interest.
3712 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3713 * optional numbers of mesh entities.
3714 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3715 * delete using decrRef() as it is no more needed.
3716 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3718 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3721 synchronizeTinyInfoOnLeaves();
3722 if(meshDimRelToMaxExt==1)
3726 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3727 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3728 umesh->setCoords(cc);
3729 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3730 umesh->setName(getName());
3734 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3735 return l1->getWholeMesh(renum);
3738 std::vector<mcIdType> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3740 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3741 return l1->getDistributionOfTypes();
3745 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3746 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3747 * optional numbers of mesh entities.
3748 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3749 * delete using decrRef() as it is no more needed.
3750 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3752 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3754 return getMeshAtLevel(0,renum);
3758 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3759 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3760 * optional numbers of mesh entities.
3761 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3762 * delete using decrRef() as it is no more needed.
3763 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3765 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3767 return getMeshAtLevel(-1,renum);
3771 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3772 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3773 * optional numbers of mesh entities.
3774 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3775 * delete using decrRef() as it is no more needed.
3776 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3778 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3780 return getMeshAtLevel(-2,renum);
3784 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3785 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3786 * optional numbers of mesh entities.
3787 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3788 * delete using decrRef() as it is no more needed.
3789 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3791 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3793 return getMeshAtLevel(-3,renum);
3797 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3798 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3799 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3800 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3802 void MEDFileUMesh::forceComputationOfParts() const
3804 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3806 const MEDFileUMeshSplitL1 *elt(*it);
3808 elt->forceComputationOfParts();
3813 * This method returns a vector of mesh parts containing each exactly one geometric type.
3814 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3815 * This method is only for memory aware users.
3816 * The returned pointers are **NOT** new object pointer. No need to mange them.
3818 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3821 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3822 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3826 * This method returns the part of \a this having the geometric type \a gt.
3827 * If such part is not existing an exception will be thrown.
3828 * The returned pointer is **NOT** new object pointer. No need to mange it.
3830 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3833 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3834 int lev=(int)cm.getDimension()-getMeshDimension();
3835 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3836 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3840 * This method returns for each geo types in \a this number of cells with this geo type.
3841 * 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.
3842 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3844 * \sa getDistributionOfTypes
3846 std::vector< std::pair<int,mcIdType> > MEDFileUMesh::getAllDistributionOfTypes() const
3848 std::vector< std::pair<int,mcIdType> > ret;
3849 std::vector<int> nel(getNonEmptyLevels());
3850 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3852 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3853 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3855 mcIdType nbCells(getNumberOfCellsWithType(*it1));
3856 ret.push_back(std::pair<int,mcIdType>(*it1,nbCells));
3859 ret.push_back(std::pair<int,mcIdType>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3864 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3865 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3867 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3869 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3870 return sp->getGeoTypes();
3873 mcIdType MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3875 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3876 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3877 return sp->getNumberOfCellsWithType(ct);
3881 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3882 * \param [in] gt - the geometric type for which the family field is asked.
3883 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
3884 * delete using decrRef() as it is no more needed.
3885 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3887 DataArrayIdType *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3889 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3890 int lev=(int)cm.getDimension()-getMeshDimension();
3891 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3892 return sp->extractFamilyFieldOnGeoType(gt);
3896 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3897 * \param [in] gt - the geometric type for which the number field is asked.
3898 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
3899 * delete using decrRef() as it is no more needed.
3900 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3902 DataArrayIdType *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3904 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3905 int lev=(int)cm.getDimension()-getMeshDimension();
3906 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3907 return sp->extractNumberFieldOnGeoType(gt);
3911 * This method returns for specified geometric type \a gt the relative level to \a this.
3912 * If the relative level is empty an exception will be thrown.
3914 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3916 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3917 int ret((int)cm.getDimension()-getMeshDimension());
3918 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3922 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3924 if(meshDimRelToMaxExt==1)
3925 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3926 if(meshDimRelToMaxExt>1)
3927 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3928 int tracucedRk=-meshDimRelToMaxExt;
3929 if(tracucedRk>=(int)_ms.size())
3930 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3931 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3932 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3933 return _ms[tracucedRk];
3936 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3938 if(meshDimRelToMaxExt==1)
3939 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3940 if(meshDimRelToMaxExt>1)
3941 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3942 int tracucedRk=-meshDimRelToMaxExt;
3943 if(tracucedRk>=(int)_ms.size())
3944 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3945 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3946 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3947 return _ms[tracucedRk];
3950 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3952 if(-meshDimRelToMax>=(int)_ms.size())
3953 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3955 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3957 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3959 int ref=(*it)->getMeshDimension();
3960 if(ref+i!=meshDim-meshDimRelToMax)
3961 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3967 * Sets the node coordinates array of \a this mesh.
3968 * \param [in] coords - the new node coordinates array.
3969 * \throw If \a coords == \c NULL.
3971 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3974 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3975 if(coords==(DataArrayDouble *)_coords)
3977 coords->checkAllocated();
3978 mcIdType nbOfTuples(coords->getNumberOfTuples());
3979 _coords.takeRef(coords);
3980 _fam_coords=DataArrayIdType::New();
3981 _fam_coords->alloc(nbOfTuples,1);
3982 _fam_coords->fillWithZero();
3983 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3984 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3985 if((MEDFileUMeshSplitL1 *)(*it))
3986 (*it)->setCoords(coords);
3990 * Change coords without changing anything concerning families and numbering on nodes.
3992 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3995 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3996 if(coords==(DataArrayDouble *)_coords)
3998 coords->checkAllocated();
3999 mcIdType nbOfTuples(coords->getNumberOfTuples());
4000 if(_coords.isNull())
4007 mcIdType oldNbTuples(_coords->getNumberOfTuples());
4008 if(oldNbTuples!=nbOfTuples)
4009 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
4013 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4014 if((MEDFileUMeshSplitL1 *)(*it))
4015 (*it)->setCoords(coords);
4019 * Removes all groups of a given dimension in \a this mesh.
4020 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4021 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4023 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
4025 if(meshDimRelToMaxExt==1)
4027 if((DataArrayIdType *)_fam_coords)
4028 _fam_coords->fillWithZero();
4031 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
4032 l1->eraseFamilyField();
4037 * Removes all families with ids not present in the family fields of \a this mesh.
4039 void MEDFileUMesh::optimizeFamilies()
4041 std::vector<int> levs=getNonEmptyLevelsExt();
4042 std::set<mcIdType> allFamsIds;
4043 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4045 const DataArrayIdType *ffield=getFamilyFieldAtLevel(*it);
4046 MCAuto<DataArrayIdType> ids=ffield->getDifferentValues();
4047 std::set<mcIdType> res;
4048 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
4051 std::set<std::string> famNamesToKill;
4052 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
4054 if(allFamsIds.find((*it).second)!=allFamsIds.end())
4055 famNamesToKill.insert((*it).first);
4057 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
4058 _families.erase(*it);
4059 std::vector<std::string> grpNamesToKill;
4060 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
4062 std::vector<std::string> tmp;
4063 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
4065 if(famNamesToKill.find(*it2)==famNamesToKill.end())
4066 tmp.push_back(*it2);
4071 tmp.push_back((*it).first);
4073 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
4078 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
4079 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
4080 * The boundary is built according to the following method:
4081 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
4082 * coordinates array is extended).
4083 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
4084 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
4085 * might not be duplicated at all.
4086 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
4087 * other side of the group is no more a neighbor)
4088 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
4089 * bordering the newly created boundary use the newly computed nodes.
4090 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
4091 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
4093 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
4094 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
4096 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
4097 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
4098 * \sa clearNodeAndCellNumbers()
4100 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayIdType *&nodesDuplicated,
4101 DataArrayIdType *&cellsModified, DataArrayIdType *&cellsNotModified)
4103 typedef MCAuto<MEDCouplingUMesh> MUMesh;
4104 typedef MCAuto<DataArrayIdType> DAInt;
4106 std::vector<int> levs=getNonEmptyLevels();
4107 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
4108 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
4109 MUMesh m0=getMeshAtLevel(0);
4110 MUMesh m1=getMeshAtLevel(-1);
4111 mcIdType nbNodes=m0->getNumberOfNodes();
4112 MUMesh m11=getGroup(-1,grpNameM1);
4113 DataArrayIdType *tmp00=0,*tmp11=0,*tmp22=0;
4114 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
4115 DAInt nodeIdsToDuplicate(tmp00);
4116 DAInt cellsToModifyConn0(tmp11);
4117 DAInt cellsToModifyConn1(tmp22);
4118 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4119 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4120 DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New();
4121 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4122 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4123 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4124 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4125 DataArrayIdType *cellsInM1ToRenumW4Tmp=0;
4126 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4127 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4128 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4129 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4130 DAInt grpIds=getGroupArr(-1,grpNameM1);
4131 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4132 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4133 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4134 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4135 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4136 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4137 m0->setCoords(tmp0->getCoords());
4138 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4139 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4140 m1->setCoords(m0->getCoords());
4141 _coords=m0->getCoords(); _coords->incrRef();
4142 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4143 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4144 DataArrayIdType * duplCells;
4145 m1->areCellsIncludedIn(m11, 0, duplCells);
4146 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4147 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4148 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4149 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4150 DAInt szOfCellGrpOfSameType(tmp00);
4151 DAInt idInMsOfCellGrpOfSameType(tmp11);
4153 newm1->setName(getName());
4154 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
4156 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4157 DAInt newFam=DataArrayIdType::New();
4158 newFam->alloc(newm1->getNumberOfCells(),1);
4159 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4160 // Positive ID for family of nodes, negative for all the rest.
4162 if (m1->getMeshDimension() == 0)
4163 idd=getMaxFamilyId()+1;
4165 idd=getMinFamilyId()-1;
4166 mcIdType globStart=0,start=0,end,globEnd;
4167 mcIdType nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4168 for(mcIdType i=0;i<nbOfChunks;i++)
4170 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4171 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4173 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4174 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4175 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4180 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4184 newm1->setCoords(getCoords());
4185 setMeshAtLevel(-1,newm1);
4186 setFamilyFieldArr(-1,newFam);
4187 std::string grpName2(grpNameM1); grpName2+="_dup";
4188 addFamily(grpName2,idd);
4189 addFamilyOnGrp(grpName2,grpName2);
4194 mcIdType newNbOfNodes=getCoords()->getNumberOfTuples();
4195 newFam=DataArrayIdType::New(); newFam->alloc(newNbOfNodes,1);
4196 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4197 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4201 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4203 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4204 it != _ms.end(); it++)
4207 (*it)->_rev_num = 0;
4209 nodesDuplicated=nodeIdsToDuplicate.retn();
4210 cellsModified=cellsToModifyConn0.retn();
4211 cellsNotModified=cellsToModifyConn1.retn();
4214 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4215 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4218 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4219 * \param [out] newCode retrieves the distribution of types after the call if true is returned
4220 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4222 * \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.
4223 * 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.
4225 bool MEDFileUMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
4227 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4228 std::vector<int> levs=getNonEmptyLevels();
4230 std::vector< const DataArrayIdType* > renumCellsSplited;//same than memorySaverIfThrow
4231 std::vector< MCAuto<DataArrayIdType> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4234 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4236 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4237 std::vector<mcIdType> code1=m->getDistributionOfTypes();
4238 end=PutInThirdComponentOfCodeOffset(code1,start);
4239 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4240 bool hasChanged=m->unPolyze();
4241 DataArrayIdType *fake=0;
4242 MCAuto<DataArrayIdType> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4243 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4245 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4248 MCAuto<DataArrayIdType> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4249 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4251 MCAuto<DataArrayIdType> famField2,numField2;
4252 const DataArrayIdType *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayIdType *>(famField); }
4253 const DataArrayIdType *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayIdType *>(numField); }
4254 setMeshAtLevel(*it,m);
4255 std::vector<mcIdType> code2=m->getDistributionOfTypes();
4256 end=PutInThirdComponentOfCodeOffset(code2,start);
4257 newCode.insert(newCode.end(),code2.begin(),code2.end());
4259 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4263 MCAuto<DataArrayIdType> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4264 setFamilyFieldArr(*it,newFamField);
4268 MCAuto<DataArrayIdType> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4269 setRenumFieldArr(*it,newNumField);
4274 newCode.insert(newCode.end(),code1.begin(),code1.end());
4280 MCAuto<DataArrayIdType> renumCells=DataArrayIdType::Aggregate(renumCellsSplited);
4281 MCAuto<DataArrayIdType> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4282 o2nRenumCell=o2nRenumCellRet.retn();
4287 /*! \cond HIDDEN_ITEMS */
4288 struct MEDLoaderAccVisit1
4290 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4291 mcIdType operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4292 mcIdType _new_nb_of_nodes;
4297 * 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.
4298 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4299 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4300 * -1 values in returned array means that the corresponding old node is no more used.
4302 * \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
4303 * is modified in \a this.
4304 * \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
4307 DataArrayIdType *MEDFileUMesh::zipCoords()
4309 const DataArrayDouble *coo(getCoords());
4311 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4312 mcIdType nbOfNodes(coo->getNumberOfTuples());
4313 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4314 std::vector<int> neLevs(getNonEmptyLevels());
4315 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4317 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4318 if(zeLev->isMeshStoredSplitByType())
4320 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4321 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4323 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4327 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4328 mesh->computeNodeIdsAlg(nodeIdsInUse);
4331 mcIdType nbrOfNodesInUse((mcIdType)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4332 if(nbrOfNodesInUse==nbOfNodes)
4333 return 0;//no need to update _part_coords
4334 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfNodes,1);
4335 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4336 MCAuto<DataArrayIdType> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4337 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4338 MCAuto<DataArrayIdType> newFamCoords;
4339 MCAuto<DataArrayAsciiChar> newNameCoords;
4340 if((const DataArrayIdType *)_fam_coords)
4341 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4342 MCAuto<DataArrayIdType> newNumCoords,newGlobalNumCoords;
4343 if(_num_coords.isNotNull())
4344 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4345 if(_global_num_coords.isNotNull())
4346 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4347 if(_name_coords.isNotNull())
4348 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4349 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4350 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4352 if((MEDFileUMeshSplitL1*)*it)
4354 (*it)->renumberNodesInConn(ret->begin());
4355 (*it)->setCoords(_coords);
4358 // updates _part_coords
4359 const PartDefinition *pc(_part_coords);
4362 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4363 _part_coords=tmpPD->composeWith(pc);
4369 * This method is the extension of MEDCouplingUMesh::computeFetchedNodeIds. Except that here all levels are considered here.
4371 * \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.
4373 DataArrayIdType *MEDFileUMesh::computeFetchedNodeIds() const
4375 std::vector<int> neLevs(this->getNonEmptyLevels());
4376 std::vector<bool> nodesHighlighted(this->getNumberOfNodes(),false);
4377 for(auto lev : neLevs)
4379 const MEDFileUMeshSplitL1 *zeLev(this->getMeshAtLevSafe(lev));
4380 zeLev->highlightUsedNodes(nodesHighlighted);
4382 return DataArrayIdType::BuildListOfSwitchedOn(nodesHighlighted);
4386 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4387 * The extraction of \a this is specified by the extractDef \a input map.
4388 * This map tells for each level of cells, the cells kept in the extraction.
4390 * \return - a new reference of DataArrayIdType that represents sorted node ids, the extraction is lying on.
4391 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4393 DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4395 std::vector<int> levs(getNonEmptyLevels());
4396 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4397 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4400 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4401 if((*it).second.isNull())
4402 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4405 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4407 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4408 throw INTERP_KERNEL::Exception(oss.str());
4410 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4411 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4412 mPart->computeNodeIdsAlg(fetchedNodes);
4414 return DataArrayIdType::BuildListOfSwitchedOn(fetchedNodes);
4418 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4420 * \return - a new reference of MEDFileUMesh
4421 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4423 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4425 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4426 std::vector<int> levs(getNonEmptyLevels());
4427 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4430 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4431 if((*it).second.isNull())
4432 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4435 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4437 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4438 throw INTERP_KERNEL::Exception(oss.str());
4440 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4441 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4442 ret->setMeshAtLevel((*it).first,mPart);
4443 const DataArrayIdType *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4446 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4447 ret->setFamilyFieldArr((*it).first,famPart);
4451 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4452 ret->setFamilyFieldArr((*it).first,numPart);
4455 std::map<int, MCAuto<DataArrayIdType> >::const_iterator it2(extractDef.find(1));
4456 if(it2!=extractDef.end())
4458 const DataArrayDouble *coo(ret->getCoords());
4460 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4461 MCAuto<DataArrayIdType> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4462 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4463 ret->setCoords(cooPart);
4464 const DataArrayIdType *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4467 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4468 ret->setFamilyFieldArr(1,famPart);
4472 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4473 ret->setFamilyFieldArr(1,numPart);
4475 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4479 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4480 m->renumberNodesInConn(o2nNodes->begin());
4481 ret->setMeshAtLevel((*it3).first,m);
4488 * This method performs an extrusion along a path defined by \a m1D.
4489 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4490 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4491 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4492 * This method scans all levels in \a this
4493 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4495 * \param [in] m1D - the mesh defining the extrusion path.
4496 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4497 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4499 * \sa MEDCouplingUMesh::buildExtrudedMesh
4501 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4504 if(getMeshDimension()!=2)
4505 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4506 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4507 m1D->checkConsistencyLight();
4508 if(m1D->getMeshDimension()!=1)
4509 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4510 mcIdType nbRep(m1D->getNumberOfCells());
4511 std::vector<int> levs(getNonEmptyLevels());
4512 std::vector<std::string> grps(getGroupsNames());
4513 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4514 DataArrayDouble *coords(0);
4515 std::size_t nbOfLevsOut(levs.size()+1);
4516 std::vector< MCAuto<DataArrayIdType> > o2ns(nbOfLevsOut);
4517 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4519 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4520 item=item->clone(false);
4521 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4522 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4523 tmp->changeSpaceDimension(3+(*lev),0.);
4524 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4525 zeList.push_back(elt);
4527 coords=elt->getCoords();
4530 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4531 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4533 (*it)->setName(getName());
4534 (*it)->setCoords(coords);
4536 for(std::size_t ii=0;ii!=zeList.size();ii++)
4539 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4542 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4543 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4544 MCAuto<DataArrayIdType> tmp(elt2->getNodalConnectivity()->deepCopy());
4545 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4546 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4547 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4548 std::vector<const MEDCouplingUMesh *> elts(3);
4549 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4550 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4551 elt->setName(getName());
4554 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4555 ret->setMeshAtLevel(lev,elt);
4557 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4558 endLev=endLev->clone(false); endLev->setCoords(coords);
4559 MCAuto<DataArrayIdType> tmp(endLev->getNodalConnectivity()->deepCopy());
4560 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4561 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4562 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4563 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4564 endLev->setName(getName());
4565 ret->setMeshAtLevel(levs.back()-1,endLev);
4567 for(std::size_t ii=0;ii!=zeList.size();ii++)
4570 std::vector< MCAuto<DataArrayIdType> > outGrps;
4571 std::vector< const DataArrayIdType * > outGrps2;
4574 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4576 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev+1,*grp));
4577 if(!grpArr->empty())
4579 MCAuto<DataArrayIdType> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4580 mcIdType offset0(zeList[ii]->getNumberOfCells());
4581 mcIdType offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4582 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4583 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4584 grpArr2->setName(oss.str());
4585 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4586 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4587 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4588 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4593 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4595 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev,*grp));
4596 if(!grpArr->empty())
4598 mcIdType nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4599 std::vector< MCAuto<DataArrayIdType> > grpArrs(nbRep);
4600 std::vector< const DataArrayIdType *> grpArrs2(nbRep);
4601 for(int iii=0;iii<nbRep;iii++)
4603 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4604 grpArrs2[iii]=grpArrs[iii];
4606 MCAuto<DataArrayIdType> grpArrExt(DataArrayIdType::Aggregate(grpArrs2));
4607 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4608 std::ostringstream grpName; grpName << *grp << "_extruded";
4609 grpArrExt->setName(grpName.str());
4610 outGrps.push_back(grpArrExt);
4611 outGrps2.push_back(grpArrExt);
4614 ret->setGroupsAtLevel(lev,outGrps2);
4616 std::vector< MCAuto<DataArrayIdType> > outGrps;
4617 std::vector< const DataArrayIdType * > outGrps2;
4618 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4620 MCAuto<DataArrayIdType> grpArr1(getGroupArr(levs.back(),*grp));
4621 if(grpArr1->empty())
4623 MCAuto<DataArrayIdType> grpArr2(grpArr1->deepCopy());
4624 std::ostringstream grpName; grpName << *grp << "_top";
4625 grpArr2->setName(grpName.str());
4626 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4627 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4628 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4630 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4635 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4636 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4637 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4639 * \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
4640 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4641 * \param [in] eps - detection threshold for coordinates.
4642 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4644 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4646 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4649 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4650 mcIdType initialNbNodes(getNumberOfNodes());
4651 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4652 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4654 MCAuto<DataArrayIdType> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4656 DataArrayDouble *zeCoords(m0->getCoords());
4657 ret->setMeshAtLevel(0,m0);
4658 std::vector<int> levs(getNonEmptyLevels());
4659 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4662 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4663 ret->setFamilyFieldArr(0,famFieldCpy);
4665 famField=getFamilyFieldAtLevel(1);
4668 MCAuto<DataArrayIdType> fam(DataArrayIdType::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4669 fam->fillWithZero();
4670 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4671 ret->setFamilyFieldArr(1,fam);
4673 ret->copyFamGrpMapsFrom(*this);
4674 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4675 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4679 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4680 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4681 if(m1->getMeshDimension()!=0)
4684 MCAuto<DataArrayIdType> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4685 }//kill unused notUsed var
4686 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4687 DataArrayIdType *b(0);
4688 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4689 MCAuto<DataArrayIdType> bSafe(b);
4692 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4693 throw INTERP_KERNEL::Exception(oss.str().c_str());
4695 b->applyLin(1,initialNbNodes);
4696 MCAuto<DataArrayIdType> l0(DataArrayIdType::New()); l0->alloc(initialNbNodes,1); l0->iota();
4697 std::vector<const DataArrayIdType *> v(2); v[0]=l0; v[1]=b;
4698 MCAuto<DataArrayIdType> renum(DataArrayIdType::Aggregate(v));
4699 m1->renumberNodesInConn(renum->begin());
4701 m1->setCoords(zeCoords);
4702 ret->setMeshAtLevel(*lev,m1);
4703 famField=getFamilyFieldAtLevel(*lev);
4706 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4707 ret->setFamilyFieldArr(*lev,famFieldCpy);
4714 * This method converts all quadratic cells in \a this into linear cells.
4715 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4716 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4718 * \param [in] eps - detection threshold for coordinates.
4719 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4721 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4723 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4726 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4727 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4728 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4729 m0->convertQuadraticCellsToLinear();
4731 DataArrayDouble *zeCoords(m0->getCoords());
4732 ret->setMeshAtLevel(0,m0);
4733 std::vector<int> levs(getNonEmptyLevels());
4734 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4737 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4738 ret->setFamilyFieldArr(0,famFieldCpy);
4740 famField=getFamilyFieldAtLevel(1);
4743 MCAuto<DataArrayIdType> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4744 ret->setFamilyFieldArr(1,fam);
4746 ret->copyFamGrpMapsFrom(*this);
4747 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4751 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4752 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4753 m1->convertQuadraticCellsToLinear();
4755 DataArrayIdType *b(0);
4756 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4757 MCAuto<DataArrayIdType> bSafe(b);
4760 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4761 throw INTERP_KERNEL::Exception(oss.str().c_str());
4763 m1->renumberNodesInConn(b->begin());
4764 m1->setCoords(zeCoords);
4765 ret->setMeshAtLevel(*lev,m1);
4766 famField=getFamilyFieldAtLevel(*lev);
4769 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4770 ret->setFamilyFieldArr(*lev,famFieldCpy);
4777 * Computes the symmetry of \a this.
4778 * \return a new object.
4780 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4782 MCAuto<MEDFileUMesh> ret(deepCopy());
4783 DataArrayDouble *myCoo(getCoords());
4786 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4787 ret->setCoordsForced(newCoo);
4793 * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
4794 * merged in such a way that the final mesh contain all of them.
4795 * \return a new object.
4797 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4800 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4801 std::size_t sz(meshes.size()),i(0);
4802 std::vector<const DataArrayDouble *> coos(sz);
4803 std::vector<const DataArrayIdType *> fam_coos(sz),num_coos(sz);
4804 for(auto it=meshes.begin();it!=meshes.end();it++,i++)
4807 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4808 coos[i]=(*it)->getCoords();
4809 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4810 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4812 const MEDFileUMesh *ref(meshes[0]);
4813 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4814 std::vector<int> levs(ref->getNonEmptyLevels());
4815 std::map<int, std::vector<const DataArrayIdType *> > m_fam,m_renum;
4816 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4817 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4818 std::map<std::string,mcIdType> famNumMap;
4819 std::map<mcIdType, std::string> famNumMap_rev;
4820 std::map<std::string, std::vector<std::string> > grpFamMap;
4821 std::set< MCAuto<DataArrayIdType> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
4823 // Identify min family number used:
4824 mcIdType min_fam_num(0);
4825 for(const auto& msh : meshes)
4827 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4828 for(const auto& it3 : locMap1)
4829 if(it3.second < min_fam_num)
4830 min_fam_num = it3.second;
4833 for(const auto& msh : meshes)
4835 if(msh->getSpaceDimension()!=spaceDim)
4836 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4837 if(msh->getMeshDimension()!=meshDim)
4838 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4839 if(msh->getNonEmptyLevels()!=levs)
4840 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4842 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4843 std::map<std::string, std::string> substitute;
4844 std::map<mcIdType, mcIdType> substituteN;
4845 bool fam_conflict(false);
4846 for(const auto& it3 : locMap1)
4848 const std::string& famName = it3.first;
4849 mcIdType famNum = it3.second;
4850 if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
4852 // Is it used by a group of the current mesh or a group from a previous mesh?
4853 // If not, this is OK (typically -1 familly).
4856 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4857 for(const auto& it4 : locMap2)
4859 const auto& famLst = it4.second;
4860 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4861 { used = true; break; }
4863 // Previous meshes ...
4865 for(const auto& it4 : grpFamMap)
4867 const auto& famLst = it4.second;
4868 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4869 { used = true; break; }
4873 { // Generate a new family name, and a new family number
4874 fam_conflict = true;
4875 std::ostringstream oss;
4876 oss << "Family_" << --min_fam_num; // New ID
4877 std::string new_name(oss.str());
4878 substitute[famName] = new_name;
4879 substituteN[famNum] = min_fam_num;
4880 famNumMap[new_name] = min_fam_num;
4881 famNumMap_rev[min_fam_num] = new_name;
4884 famNumMap[famName] = famNum;
4885 famNumMap_rev[famNum] = famName;
4888 for(const auto& level : levs)
4890 MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
4891 m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
4892 m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
4894 // Family field - substitute new family number if needed:
4897 DataArrayIdType* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
4898 mem_cleanup.insert(MCAuto<DataArrayIdType>(dai)); // Make sure array will decrRef() at end of method
4899 for (const auto& subN : substituteN)
4900 dai->changeValue(subN.first, subN.second);
4901 m_fam[level].push_back(dai);
4904 m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
4907 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4908 for(const auto& grpItem : locMap2)
4910 const std::string& grpName = grpItem.first;
4911 std::vector<std::string> famLst;
4912 // Substitute family name in group description if needed:
4915 famLst = grpItem.second;
4916 for (const auto& sub : substitute)
4917 std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
4920 famLst = grpItem.second;
4922 // Potentially merge groups (if same name):
4923 const auto& it = grpFamMap.find(grpName);
4924 if (it != grpFamMap.end())
4926 // Group already exists, merge should be done. Normally we whould never
4927 // have twice the same family name in famLstCur and famLst since we dealt with family number
4928 // conflict just above ...
4929 std::vector<std::string>& famLstCur = (*it).second;
4930 famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
4933 grpFamMap[grpName] = famLst;
4936 // Easy part : nodes
4937 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4938 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4939 ret->setCoords(coo);
4940 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayIdType *)0)==fam_coos.end())
4942 MCAuto<DataArrayIdType> fam_coo(DataArrayIdType::Aggregate(fam_coos));
4943 ret->setFamilyFieldArr(1,fam_coo);
4945 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayIdType *)0)==num_coos.end())
4947 MCAuto<DataArrayIdType> num_coo(DataArrayIdType::Aggregate(num_coos));
4948 ret->setRenumFieldArr(1,num_coo);
4951 for(const auto& level : levs)
4953 auto it2(m_mesh.find(level));
4954 if(it2==m_mesh.end())
4955 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4956 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4957 mesh->setCoords(coo); mesh->setName(ref->getName());
4958 MCAuto<DataArrayIdType> renum(mesh->sortCellsInMEDFileFrmt());
4959 ret->setMeshAtLevel(level,mesh);
4960 auto it3(m_fam.find(level)),it4(m_renum.find(level));
4961 if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
4962 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
4963 if(it4==m_renum.end())
4964 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
4965 // Set new family field if it was defined for all input meshes
4966 const std::vector<const DataArrayIdType *>& fams((*it3).second);
4967 if(std::find(fams.begin(),fams.end(),(const DataArrayIdType *)0)==fams.end())
4969 MCAuto<DataArrayIdType> famm(DataArrayIdType::Aggregate(fams));
4970 famm->renumberInPlace(renum->begin());
4971 ret->setFamilyFieldArr(level,famm);
4973 // Set optional number field if defined for all input meshes:
4974 const std::vector<const DataArrayIdType *>& renums((*it4).second);
4975 if(std::find(renums.begin(),renums.end(),(const DataArrayIdType *)0)==renums.end())
4977 MCAuto<DataArrayIdType> renumm(DataArrayIdType::Aggregate(renums));
4978 renumm->renumberInPlace(renum->begin());
4979 ret->setRenumFieldArr(level,renumm);
4983 ret->setFamilyInfo(famNumMap);
4984 ret->setGroupInfo(grpFamMap);
4985 ret->setName(ref->getName());
4989 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4991 if(getMeshDimension()!=3)
4992 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4993 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4994 if(m3D.isNull() || m2D.isNull())
4995 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4996 mcIdType zeId(std::numeric_limits<med_int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4997 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
5001 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5003 clearNonDiscrAttributes();
5004 forceComputationOfParts();
5005 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
5006 std::vector<mcIdType> layer0;
5007 layer0.push_back(getAxisType());//0 i
5008 layer0.push_back(_order); //1 i
5009 layer0.push_back(_iteration);//2 i
5010 layer0.push_back(getSpaceDimension());//3 i
5011 tinyDouble.push_back(_time);//0 d
5012 tinyStr.push_back(_name);//0 s
5013 tinyStr.push_back(_desc_name);//1 s
5014 for(int i=0;i<getSpaceDimension();i++)
5015 tinyStr.push_back(_coords->getInfoOnComponent(i));
5016 layer0.push_back(ToIdType(_families.size()));//4 i <- key info aa layer#0
5017 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
5019 tinyStr.push_back((*it).first);
5020 layer0.push_back((*it).second);
5022 layer0.push_back((mcIdType)_groups.size());//4+aa i <- key info bb layer#0
5023 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
5025 layer0.push_back(ToIdType((*it0).second.size()));
5026 tinyStr.push_back((*it0).first);
5027 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
5028 tinyStr.push_back(*it1);
5030 // sizeof(layer0)==4+aa+1+bb layer#0
5031 bigArrayD=_coords;// 0 bd
5032 bigArraysI.push_back(_fam_coords);// 0 bi
5033 bigArraysI.push_back(_num_coords);// 1 bi
5034 const PartDefinition *pd(_part_coords);
5036 layer0.push_back(-1);
5039 std::vector<mcIdType> tmp0;
5040 pd->serialize(tmp0,bigArraysI);
5041 tinyInt.push_back(ToIdType(tmp0.size()));
5042 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
5045 std::vector<mcIdType> layer1;
5046 std::vector<int> levs(getNonEmptyLevels());
5047 layer1.push_back((mcIdType)levs.size());// 0 i <- key
5048 layer1.insert(layer1.end(),levs.begin(),levs.end());
5049 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
5051 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
5052 lev->serialize(layer1,bigArraysI);
5054 // put layers all together.
5055 tinyInt.push_back(ToIdType(layer0.size()));
5056 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
5057 tinyInt.push_back(ToIdType(layer1.size()));
5058 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
5061 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr,
5062 std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5064 mcIdType sz0(tinyInt[0]);
5065 std::vector<mcIdType> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
5066 mcIdType sz1(tinyInt[sz0+1]);
5067 std::vector<mcIdType> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
5069 std::reverse(layer0.begin(),layer0.end());
5070 std::reverse(layer1.begin(),layer1.end());
5071 std::reverse(tinyDouble.begin(),tinyDouble.end());
5072 std::reverse(tinyStr.begin(),tinyStr.end());
5073 std::reverse(bigArraysI.begin(),bigArraysI.end());
5075 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
5076 _order=FromIdType<int>(layer0.back()); layer0.pop_back();
5077 _iteration=FromIdType<int>(layer0.back()); layer0.pop_back();
5078 mcIdType spaceDim(layer0.back()); layer0.pop_back();
5079 _time=tinyDouble.back(); tinyDouble.pop_back();
5080 _name=tinyStr.back(); tinyStr.pop_back();
5081 _desc_name=tinyStr.back(); tinyStr.pop_back();
5082 _coords=bigArrayD; _coords->rearrange(spaceDim);
5083 for(int i=0;i<spaceDim;i++)
5085 _coords->setInfoOnComponent(i,tinyStr.back());
5088 mcIdType nbOfFams(layer0.back()); layer0.pop_back();
5090 for(mcIdType i=0;i<nbOfFams;i++)
5092 _families[tinyStr.back()]=layer0.back();
5093 tinyStr.pop_back(); layer0.pop_back();
5095 mcIdType nbGroups(layer0.back()); layer0.pop_back();
5097 for(mcIdType i=0;i<nbGroups;i++)
5099 std::string grpName(tinyStr.back()); tinyStr.pop_back();
5100 mcIdType nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
5101 std::vector<std::string> fams(nbOfFamsOnGrp);
5102 for(mcIdType j=0;j<nbOfFamsOnGrp;j++)
5104 fams[j]=tinyStr.back(); tinyStr.pop_back();
5106 _groups[grpName]=fams;
5108 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
5109 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
5111 mcIdType isPd(layer0.back()); layer0.pop_back();
5114 std::vector<mcIdType> tmp0(layer0.begin(),layer0.begin()+isPd);
5115 layer0.erase(layer0.begin(),layer0.begin()+isPd);
5116 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
5119 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
5121 mcIdType nbLevs(layer1.back()); layer1.pop_back();
5122 std::vector<mcIdType> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
5124 mcIdType maxLev(-(*std::min_element(levs.begin(),levs.end())));
5125 _ms.resize(maxLev+1);
5126 for(mcIdType i=0;i<nbLevs;i++)
5128 mcIdType lev(levs[i]);
5130 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
5135 * Adds a group of nodes to \a this mesh.
5136 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5137 * The ids should be sorted and different each other (MED file norm).
5139 * \warning this method can alter default "FAMILLE_ZERO" family.
5140 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5142 * \throw If the node coordinates array is not set.
5143 * \throw If \a ids == \c NULL.
5144 * \throw If \a ids->getName() == "".
5145 * \throw If \a ids does not respect the MED file norm.
5146 * \throw If a group with name \a ids->getName() already exists.
5148 void MEDFileUMesh::addNodeGroup(const DataArrayIdType *ids)
5150 const DataArrayDouble *coords(_coords);
5152 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
5153 mcIdType nbOfNodes(coords->getNumberOfTuples());
5154 if(_fam_coords.isNull())
5155 { _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
5157 addGroupUnderground(true,ids,_fam_coords);
5161 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5163 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5164 * The ids should be sorted and different each other (MED file norm).
5166 * \warning this method can alter default "FAMILLE_ZERO" family.
5167 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5169 * \throw If the node coordinates array is not set.
5170 * \throw If \a ids == \c NULL.
5171 * \throw If \a ids->getName() == "".
5172 * \throw If \a ids does not respect the MED file norm.
5173 * \throw If a group with name \a ids->getName() already exists.
5175 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
5177 std::vector<int> levs(getNonEmptyLevelsExt());
5178 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
5180 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
5181 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
5183 if(meshDimRelToMaxExt==1)
5184 { addNodeGroup(ids); return ; }
5185 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
5186 DataArrayIdType *fam(lev->getOrCreateAndGetFamilyField());
5187 addGroupUnderground(false,ids,fam);
5191 * Changes a name of a family specified by its id.
5192 * \param [in] id - the id of the family of interest.
5193 * \param [in] newFamName - the new family name.
5194 * \throw If no family with the given \a id exists.
5196 void MEDFileUMesh::setFamilyNameAttachedOnId(mcIdType id, const std::string& newFamName)
5198 std::string oldName=getFamilyNameGivenId(id);
5199 _families.erase(oldName);
5200 _families[newFamName]=id;
5204 * Removes a mesh of a given dimension.
5205 * \param [in] meshDimRelToMax - the relative dimension of interest.
5206 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
5208 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
5210 std::vector<int> levSet=getNonEmptyLevels();
5211 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
5212 if(it==levSet.end())
5213 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
5214 int pos=(-meshDimRelToMax);
5219 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
5220 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5221 * \param [in] m - the new mesh to set.
5222 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5224 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5225 * another node coordinates array.
5226 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5227 * to the existing meshes of other levels of \a this mesh.
5229 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5231 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5232 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5236 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5237 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5238 * \param [in] m - the new mesh to set.
5239 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5240 * writing \a this mesh in a MED file.
5241 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5243 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5244 * another node coordinates array.
5245 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5246 * to the existing meshes of other levels of \a this mesh.
5248 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5250 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5251 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5254 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5256 dealWithTinyInfo(m);
5257 std::vector<int> levSet=getNonEmptyLevels();
5258 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5260 if((DataArrayDouble *)_coords==0)
5262 DataArrayDouble *c=m->getCoords();
5267 if(m->getCoords()!=_coords)
5268 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5269 int sz=(-meshDimRelToMax)+1;
5270 if(sz>=(int)_ms.size())
5272 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5276 return _ms[-meshDimRelToMax];
5280 * This method allows to set at once the content of different levels in \a this.
5281 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5283 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5284 * \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.
5285 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5287 * \throw If \a there is a null pointer in \a ms.
5288 * \sa MEDFileUMesh::setMeshAtLevel
5290 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5294 const MEDCouplingUMesh *mRef=ms[0];
5296 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5297 std::string name(mRef->getName());
5298 const DataArrayDouble *coo(mRef->getCoords());
5301 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5303 const MEDCouplingUMesh *cur(*it);
5305 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5306 if(coo!=cur->getCoords())
5307 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5308 int mdim=cur->getMeshDimension();
5309 zeDim=std::max(zeDim,mdim);
5310 if(s.find(mdim)!=s.end())
5311 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5313 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5315 int mdim=(*it)->getMeshDimension();
5316 setName((*it)->getName());
5317 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5323 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5324 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5325 * The given meshes must share the same node coordinates array.
5326 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5327 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5328 * create in \a this mesh.
5329 * \throw If \a ms is empty.
5330 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5331 * to the existing meshes of other levels of \a this mesh.
5332 * \throw If the meshes in \a ms do not share the same node coordinates array.
5333 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5334 * of the given meshes.
5335 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5336 * \throw If names of some meshes in \a ms are equal.
5337 * \throw If \a ms includes a mesh with an empty name.
5339 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5342 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5343 int sz=(-meshDimRelToMax)+1;
5344 if(sz>=(int)_ms.size())
5346 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5347 DataArrayDouble *coo=checkMultiMesh(ms);
5348 if((DataArrayDouble *)_coords==0)
5354 if((DataArrayDouble *)_coords!=coo)
5355 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5356 std::vector<DataArrayIdType *> corr;
5357 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5358 std::vector< MCAuto<DataArrayIdType> > corr3(corr.begin(),corr.end());
5359 setMeshAtLevel(meshDimRelToMax,m,renum);
5360 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5361 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5365 * Creates groups at a given level in \a this mesh from a sequence of
5366 * meshes each representing a group.
5367 * The given meshes must share the same node coordinates array.
5368 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5369 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5370 * create in \a this mesh.
5371 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5373 * \throw If \a ms is empty.
5374 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5375 * to the existing meshes of other levels of \a this mesh.
5376 * \throw If the meshes in \a ms do not share the same node coordinates array.
5377 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5378 * of the given meshes.
5379 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5380 * \throw If names of some meshes in \a ms are equal.
5381 * \throw If \a ms includes a mesh with an empty name.
5383 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5386 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5387 int sz=(-meshDimRelToMax)+1;
5388 if(sz>=(int)_ms.size())
5390 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5391 DataArrayDouble *coo=checkMultiMesh(ms);
5392 if((DataArrayDouble *)_coords==0)
5398 if((DataArrayDouble *)_coords!=coo)
5399 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5400 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5401 std::vector< MCAuto<DataArrayIdType> > corr(ms.size());
5403 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5405 DataArrayIdType *arr=0;
5406 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5410 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5411 throw INTERP_KERNEL::Exception(oss.str().c_str());
5414 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5415 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5418 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5420 const DataArrayDouble *ret=ms[0]->getCoords();
5421 int mdim=ms[0]->getMeshDimension();
5422 for(unsigned int i=1;i<ms.size();i++)
5424 ms[i]->checkConsistencyLight();
5425 if(ms[i]->getCoords()!=ret)
5426 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5427 if(ms[i]->getMeshDimension()!=mdim)
5428 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5430 return const_cast<DataArrayDouble *>(ret);
5434 * Sets the family field of a given relative dimension.
5435 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5436 * the family field is set.
5437 * \param [in] famArr - the array of the family field.
5438 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5439 * \throw If \a famArr has an invalid size.
5441 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5443 if(meshDimRelToMaxExt==1)
5450 DataArrayDouble *coo(_coords);
5452 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5453 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5454 _fam_coords.takeRef(famArr);
5457 if(meshDimRelToMaxExt>1)
5458 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5459 int traducedRk=-meshDimRelToMaxExt;
5460 if(traducedRk>=(int)_ms.size())
5461 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5462 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5463 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5464 return _ms[traducedRk]->setFamilyArr(famArr);
5468 * Sets the optional numbers of mesh entities of a given dimension.
5469 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5470 * \param [in] renumArr - the array of the numbers.
5471 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5472 * \throw If \a renumArr has an invalid size.
5474 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5476 if(meshDimRelToMaxExt==1)
5480 _num_coords.nullify();
5481 _rev_num_coords.nullify();
5484 if(_coords.isNull())
5485 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5486 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5487 _num_coords.takeRef(renumArr);
5491 if(meshDimRelToMaxExt>1)
5492 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5493 int traducedRk=-meshDimRelToMaxExt;
5494 if(traducedRk>=(int)_ms.size())
5495 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5496 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5497 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5498 return _ms[traducedRk]->setRenumArr(renumArr);
5502 * Sets the optional names of mesh entities of a given dimension.
5503 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5504 * \param [in] nameArr - the array of the names.
5505 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5506 * \throw If \a nameArr has an invalid size.
5508 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5510 if(meshDimRelToMaxExt==1)
5517 DataArrayDouble *coo(_coords);
5519 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5520 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5521 _name_coords.takeRef(nameArr);
5524 if(meshDimRelToMaxExt>1)
5525 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5526 int traducedRk=-meshDimRelToMaxExt;
5527 if(traducedRk>=(int)_ms.size())
5528 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5529 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5530 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5531 return _ms[traducedRk]->setNameArr(nameArr);
5534 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
5536 if(meshDimRelToMaxExt!=1)
5537 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5539 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5540 _global_num_coords.takeRef(globalNumArr);
5543 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5545 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5546 if((const MEDFileUMeshSplitL1 *)(*it))
5547 (*it)->synchronizeTinyInfo(*this);
5551 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5553 void MEDFileUMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
5555 DataArrayIdType *arr=_fam_coords;
5557 arr->changeValue(oldId,newId);
5558 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5560 MEDFileUMeshSplitL1 *sp=(*it);
5563 sp->changeFamilyIdArr(oldId,newId);
5568 std::list< MCAuto<DataArrayIdType> > MEDFileUMesh::getAllNonNullFamilyIds() const
5570 std::list< MCAuto<DataArrayIdType> > ret;
5571 const DataArrayIdType *da(_fam_coords);
5573 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5574 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5576 const MEDFileUMeshSplitL1 *elt(*it);
5579 da=elt->getFamilyField();
5581 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5587 void MEDFileUMesh::computeRevNum() const
5589 if(_num_coords.isNotNull())
5592 mcIdType maxValue=_num_coords->getMaxValue(pos);
5593 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5597 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5599 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5602 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5604 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5605 ret.push_back((const DataArrayIdType *)_fam_nodes);
5606 ret.push_back((const DataArrayIdType *)_num_nodes);
5607 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5608 ret.push_back((const DataArrayIdType *)_fam_cells);
5609 ret.push_back((const DataArrayIdType *)_num_cells);
5610 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5611 ret.push_back((const DataArrayIdType *)_fam_faces);
5612 ret.push_back((const DataArrayIdType *)_num_faces);
5613 ret.push_back((const DataArrayIdType *)_rev_num_nodes);
5614 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5615 ret.push_back((const DataArrayIdType *)_rev_num_cells);
5616 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5620 mcIdType MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5622 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5623 if((const DataArrayIdType *)_fam_nodes)
5625 mcIdType val=_fam_nodes->getMaxValue(tmp);
5626 ret=std::max(ret,std::abs(val));
5628 if((const DataArrayIdType *)_fam_cells)
5630 mcIdType val=_fam_cells->getMaxValue(tmp);
5631 ret=std::max(ret,std::abs(val));
5633 if((const DataArrayIdType *)_fam_faces)
5635 mcIdType val=_fam_faces->getMaxValue(tmp);
5636 ret=std::max(ret,std::abs(val));
5641 mcIdType MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5643 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5644 if((const DataArrayIdType *)_fam_nodes)
5646 mcIdType val=_fam_nodes->getMaxValue(tmp);
5647 ret=std::max(ret,val);
5649 if((const DataArrayIdType *)_fam_cells)
5651 mcIdType val=_fam_cells->getMaxValue(tmp);
5652 ret=std::max(ret,val);
5654 if((const DataArrayIdType *)_fam_faces)
5656 mcIdType val=_fam_faces->getMaxValue(tmp);
5657 ret=std::max(ret,val);
5662 mcIdType MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5664 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
5665 if((const DataArrayIdType *)_fam_nodes)
5667 mcIdType val=_fam_nodes->getMinValue(tmp);
5668 ret=std::min(ret,val);
5670 if((const DataArrayIdType *)_fam_cells)
5672 mcIdType val=_fam_cells->getMinValue(tmp);
5673 ret=std::min(ret,val);
5675 if((const DataArrayIdType *)_fam_faces)
5677 mcIdType val=_fam_faces->getMinValue(tmp);
5678 ret=std::min(ret,val);
5683 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5685 if(!MEDFileMesh::isEqual(other,eps,what))
5687 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5690 what="Mesh types differ ! This is structured and other is NOT !";
5693 const DataArrayIdType *famc1=_fam_nodes;
5694 const DataArrayIdType *famc2=otherC->_fam_nodes;
5695 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5697 what="Mismatch of families arr on nodes ! One is defined and not other !";
5702 bool ret=famc1->isEqual(*famc2);
5705 what="Families arr on nodes differ !";
5710 famc2=otherC->_fam_cells;
5711 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5713 what="Mismatch of families arr on cells ! One is defined and not other !";
5718 bool ret=famc1->isEqual(*famc2);
5721 what="Families arr on cells differ !";
5726 famc2=otherC->_fam_faces;
5727 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5729 what="Mismatch of families arr on faces ! One is defined and not other !";
5734 bool ret=famc1->isEqual(*famc2);
5737 what="Families arr on faces differ !";
5742 famc2=otherC->_num_nodes;
5743 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5745 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5750 bool ret=famc1->isEqual(*famc2);
5753 what="Numbering arr on nodes differ !";
5758 famc2=otherC->_num_cells;
5759 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5761 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5766 bool ret=famc1->isEqual(*famc2);
5769 what="Numbering arr on cells differ !";
5774 famc2=otherC->_num_faces;
5775 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5777 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5782 bool ret=famc1->isEqual(*famc2);
5785 what="Numbering arr on faces differ !";
5789 const DataArrayAsciiChar *d1=_names_cells;
5790 const DataArrayAsciiChar *d2=otherC->_names_cells;
5791 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5793 what="Mismatch of naming arr on cells ! One is defined and not other !";
5798 bool ret=d1->isEqual(*d2);
5801 what="Naming arr on cells differ !";
5806 d2=otherC->_names_faces;
5807 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5809 what="Mismatch of naming arr on faces ! One is defined and not other !";
5814 bool ret=d1->isEqual(*d2);
5817 what="Naming arr on faces differ !";
5822 d2=otherC->_names_nodes;
5823 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5825 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5830 bool ret=d1->isEqual(*d2);
5833 what="Naming arr on nodes differ !";
5840 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5842 MEDFileMesh::clearNonDiscrAttributes();
5843 const DataArrayIdType *tmp=_fam_nodes;
5845 (const_cast<DataArrayIdType *>(tmp))->setName("");
5848 (const_cast<DataArrayIdType *>(tmp))->setName("");
5851 (const_cast<DataArrayIdType *>(tmp))->setName("");
5854 (const_cast<DataArrayIdType *>(tmp))->setName("");
5857 (const_cast<DataArrayIdType *>(tmp))->setName("");
5860 (const_cast<DataArrayIdType *>(tmp))->setName("");
5864 * Returns ids of mesh entities contained in given families of a given dimension.
5865 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5867 * \param [in] fams - the names of the families of interest.
5868 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5869 * returned instead of ids.
5870 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
5871 * numbers, if available and required, of mesh entities of the families. The caller
5872 * is to delete this array using decrRef() as it is no more needed.
5873 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5875 DataArrayIdType *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5877 std::vector<mcIdType> famIds(getFamiliesIds(fams));
5878 switch(meshDimRelToMaxExt)
5882 if((const DataArrayIdType *)_fam_nodes)
5884 MCAuto<DataArrayIdType> da;
5886 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5888 da=_fam_nodes->findIdsEqualList(0,0);
5890 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5895 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5900 if((const DataArrayIdType *)_fam_cells)
5902 MCAuto<DataArrayIdType> da;
5904 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5906 da=_fam_cells->findIdsEqualList(0,0);
5908 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5913 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5918 if((const DataArrayIdType *)_fam_faces)
5920 MCAuto<DataArrayIdType> da;
5922 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5924 da=_fam_faces->findIdsEqualList(0,0);
5926 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5931 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5935 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5937 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5941 * Sets the family field of a given relative dimension.
5942 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5943 * the family field is set.
5944 * \param [in] famArr - the array of the family field.
5945 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5946 * \throw If \a famArr has an invalid size.
5947 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5949 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5951 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5953 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5954 switch(meshDimRelToMaxExt)
5958 mcIdType nbCells(mesh->getNumberOfCells());
5960 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5966 mcIdType nbNodes(mesh->getNumberOfNodes());
5968 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5974 mcIdType nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5976 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5981 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5988 * Sets the optional numbers of mesh entities of a given dimension.
5989 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5990 * \param [in] renumArr - the array of the numbers.
5991 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5992 * \throw If \a renumArr has an invalid size.
5993 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5995 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5997 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5999 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
6000 switch(meshDimRelToMaxExt)
6004 mcIdType nbCells=mesh->getNumberOfCells();
6005 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
6006 _num_cells=renumArr;
6011 mcIdType nbNodes=mesh->getNumberOfNodes();
6012 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
6013 _num_nodes=renumArr;
6018 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6019 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
6020 _num_faces=renumArr;
6024 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
6027 renumArr->incrRef();
6031 * Sets the optional names of mesh entities of a given dimension.
6032 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6033 * \param [in] nameArr - the array of the names.
6034 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6035 * \throw If \a nameArr has an invalid size.
6037 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
6039 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
6041 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
6042 switch(meshDimRelToMaxExt)
6046 mcIdType nbCells=mesh->getNumberOfCells();
6047 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
6048 _names_cells=nameArr;
6053 mcIdType nbNodes=mesh->getNumberOfNodes();
6054 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
6055 _names_nodes=nameArr;
6060 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6061 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
6062 _names_faces=nameArr;
6065 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6071 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
6073 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
6077 * Adds a group of nodes 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::addNodeGroup(const DataArrayIdType *ids)
6096 * Adds a group of nodes/cells/faces/edges to \a this mesh.
6098 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6099 * The ids should be sorted and different each other (MED file norm).
6101 * \warning this method can alter default "FAMILLE_ZERO" family.
6102 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6104 * \throw If the node coordinates array is not set.
6105 * \throw If \a ids == \c NULL.
6106 * \throw If \a ids->getName() == "".
6107 * \throw If \a ids does not respect the MED file norm.
6108 * \throw If a group with name \a ids->getName() already exists.
6110 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
6112 DataArrayIdType *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
6113 addGroupUnderground(false,ids,fam);
6118 * Returns the family field for mesh entities of a given dimension.
6119 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6120 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6121 * each mesh entity belongs to. It can be \c NULL.
6122 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6124 const DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
6126 switch(meshDimRelToMaxExt)
6135 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6140 * Returns the family field for mesh entities of a given dimension.
6141 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6142 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6143 * each mesh entity belongs to. It can be \c NULL.
6144 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6146 DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
6148 switch(meshDimRelToMaxExt)
6157 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6162 * Returns the optional numbers of mesh entities of a given dimension.
6163 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6164 * \return const DataArrayIdType * - the array of the entity numbers.
6165 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6166 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6168 const DataArrayIdType *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
6170 switch(meshDimRelToMaxExt)
6179 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6184 * Returns the optional numbers of mesh entities of a given dimension transformed using
6185 * DataArrayIdType::invertArrayN2O2O2N().
6186 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6187 * \return const DataArrayIdType * - the array of the entity numbers transformed using
6188 * DataArrayIdType::invertArrayN2O2O2N().
6189 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6190 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6192 const DataArrayIdType *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
6194 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
6195 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
6196 if(meshDimRelToMaxExt==0)
6198 if((const DataArrayIdType *)_num_cells)
6201 mcIdType maxValue=_num_cells->getMaxValue(pos);
6202 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
6203 return _rev_num_cells;
6206 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
6210 if((const DataArrayIdType *)_num_nodes)
6213 mcIdType maxValue=_num_nodes->getMaxValue(pos);
6214 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
6215 return _rev_num_nodes;
6218 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6222 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6224 switch(meshDimRelToMaxExt)
6227 return _names_cells;
6229 return _names_nodes;
6231 return _names_faces;
6233 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6237 MCAuto<DataArrayIdType> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6239 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6243 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6244 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6246 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6248 std::vector<int> ret(1);
6253 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6254 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6256 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6258 std::vector<int> ret(2);
6264 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6266 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6268 std::vector<int> ret;
6269 const DataArrayIdType *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6280 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6282 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6284 std::vector<int> ret;
6285 const DataArrayIdType *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6296 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6298 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6300 std::vector<int> ret;
6301 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6312 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6314 bool MEDFileStructuredMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
6316 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6320 void MEDFileStructuredMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
6322 DataArrayIdType *arr=_fam_nodes;
6324 arr->changeValue(oldId,newId);
6327 arr->changeValue(oldId,newId);
6330 arr->changeValue(oldId,newId);
6333 std::list< MCAuto<DataArrayIdType> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6335 std::list< MCAuto<DataArrayIdType> > ret;
6336 const DataArrayIdType *da(_fam_nodes);
6338 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6341 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6344 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6348 void MEDFileStructuredMesh::deepCpyAttributes()
6350 if((const DataArrayIdType*)_fam_nodes)
6351 _fam_nodes=_fam_nodes->deepCopy();
6352 if((const DataArrayIdType*)_num_nodes)
6353 _num_nodes=_num_nodes->deepCopy();
6354 if((const DataArrayAsciiChar*)_names_nodes)
6355 _names_nodes=_names_nodes->deepCopy();
6356 if((const DataArrayIdType*)_fam_cells)
6357 _fam_cells=_fam_cells->deepCopy();
6358 if((const DataArrayIdType*)_num_cells)
6359 _num_cells=_num_cells->deepCopy();
6360 if((const DataArrayAsciiChar*)_names_cells)
6361 _names_cells=_names_cells->deepCopy();
6362 if((const DataArrayIdType*)_fam_faces)
6363 _fam_faces=_fam_faces->deepCopy();
6364 if((const DataArrayIdType*)_num_faces)
6365 _num_faces=_num_faces->deepCopy();
6366 if((const DataArrayAsciiChar*)_names_faces)
6367 _names_faces=_names_faces->deepCopy();
6368 if((const DataArrayIdType*)_rev_num_nodes)
6369 _rev_num_nodes=_rev_num_nodes->deepCopy();
6370 if((const DataArrayIdType*)_rev_num_cells)
6371 _rev_num_cells=_rev_num_cells->deepCopy();
6375 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6377 * \return a pointer to cartesian mesh that need to be managed by the caller.
6378 * \warning the returned pointer has to be managed by the caller.
6382 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6383 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6384 * \param [in] renum - it must be \c false.
6385 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6386 * delete using decrRef() as it is no more needed.
6388 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6392 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6393 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6394 switch(meshDimRelToMax)
6400 return const_cast<MEDCouplingStructuredMesh *>(m);
6405 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6406 buildMinusOneImplicitPartIfNeeded();
6407 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6413 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6417 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6419 std::vector<mcIdType> ret;
6420 const DataArrayIdType *famCells(_fam_cells),*famFaces(_fam_faces);
6421 if(famCells && famCells->presenceOfValue(ret))
6423 if(famFaces && famFaces->presenceOfValue(ret))
6428 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6430 std::vector<mcIdType> ret(getFamsNonEmptyLevels(fams));
6431 const DataArrayIdType *famNodes(_fam_nodes);
6432 if(famNodes && famNodes->presenceOfValue(ret))
6438 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6439 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6440 * \return mcIdType - the number of entities.
6441 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6443 mcIdType MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6445 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6447 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6448 switch(meshDimRelToMaxExt)
6451 return cmesh->getNumberOfCells();
6453 return cmesh->getNumberOfNodes();
6455 return cmesh->getNumberOfCellsOfSubLevelMesh();
6457 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6461 mcIdType MEDFileStructuredMesh::getNumberOfNodes() const
6463 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6465 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6466 return cmesh->getNumberOfNodes();
6469 mcIdType MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6471 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6473 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6474 switch(meshDimRelToMaxExt)
6477 return cmesh->getNumberOfCells();
6479 return cmesh->getNumberOfCellsOfSubLevelMesh();
6481 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6485 bool MEDFileStructuredMesh::hasImplicitPart() const
6491 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6493 mcIdType MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6495 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6496 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6499 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6500 if(cm.getReverseExtrudedType()!=gt)
6501 throw INTERP_KERNEL::Exception(MSG);
6502 buildImplicitPart();
6503 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6507 if(gt!=zeFaceMesh->getCellModelEnum())
6508 throw INTERP_KERNEL::Exception(MSG);
6509 return zeFaceMesh->getNumberOfCells();
6513 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6515 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6517 buildImplicitPart();
6520 void MEDFileStructuredMesh::buildImplicitPart() const
6522 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6524 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6525 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6528 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6530 _faces_if_necessary=0;
6534 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6535 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6537 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6539 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6542 return _faces_if_necessary;
6545 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6547 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6549 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6550 switch(meshDimRelToMax)
6554 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6559 int mdim(cmesh->getMeshDimension());
6561 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6562 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6566 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6570 mcIdType MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6572 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6575 return getNumberOfCellsAtLevel(0);
6578 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6580 if(st.getNumberOfItems()!=1)
6581 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 !");
6582 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6583 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6584 if(getNumberOfNodes()!=(mcIdType)nodesFetched.size())
6585 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6586 if(st[0].getPflName().empty())
6588 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6591 const DataArrayIdType *arr(globs->getProfile(st[0].getPflName()));
6592 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6593 mcIdType sz(ToIdType(nodesFetched.size()));
6594 for(const mcIdType *work=arr->begin();work!=arr->end();work++)
6596 std::vector<mcIdType> conn;
6597 cmesh->getNodeIdsOfCell(*work,conn);
6598 for(std::vector<mcIdType>::const_iterator it=conn.begin();it!=conn.end();it++)
6599 if(*it>=0 && *it<sz)
6600 nodesFetched[*it]=true;
6602 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6606 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6608 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6612 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6613 MCAuto<DataArrayIdType>& famCells, MCAuto<DataArrayIdType>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6615 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6616 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6617 mcIdType nbOfElt(0);
6618 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6621 if(!mrs || mrs->isCellFamilyFieldReading())
6623 MCAuto<DataArrayMedInt> miFamCells=DataArrayMedInt::New();
6624 miFamCells->alloc(nbOfElt,1);
6625 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miFamCells->getPointer()));
6626 famCells = FromMedIntArray<mcIdType>( miFamCells );
6629 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6632 if(!mrs || mrs->isCellNumFieldReading())
6634 MCAuto<DataArrayMedInt> miNumCells=DataArrayMedInt::New();
6635 miNumCells->alloc(nbOfElt,1);
6636 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miNumCells->getPointer()));
6637 numCells = FromMedIntArray<mcIdType>( miNumCells );
6640 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6643 if(!mrs || mrs->isCellNameFieldReading())
6645 namesCells=DataArrayAsciiChar::New();
6646 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6647 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6648 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6653 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6655 setName(strm->getName());
6656 setDescription(strm->getDescription());
6657 setUnivName(strm->getUnivName());
6658 setIteration(strm->getIteration());
6659 setOrder(strm->getOrder());
6660 setTimeValue(strm->getTime());
6661 setTimeUnit(strm->getTimeUnit());
6662 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6663 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6664 mcIdType nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6667 if(!mrs || mrs->isNodeFamilyFieldReading())
6669 mcIdType nbNodes(getNumberOfNodes());
6671 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6672 MCAuto<DataArrayMedInt> miFamNodes=DataArrayMedInt::New();
6673 miFamNodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6674 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...
6675 miFamNodes->fillWithZero();
6676 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miFamNodes->getPointer()));
6677 _fam_nodes = FromMedIntArray<mcIdType>( miFamNodes );
6680 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6683 if(!mrs || mrs->isNodeNumFieldReading())
6685 MCAuto<DataArrayMedInt> miNumNodes=DataArrayMedInt::New();
6686 miNumNodes->alloc(nbOfElt,1);
6687 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miNumNodes->getPointer()));
6688 _num_nodes = FromMedIntArray<mcIdType>( miNumNodes );
6691 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6694 if(!mrs || mrs->isNodeNameFieldReading())
6696 _names_nodes=DataArrayAsciiChar::New();
6697 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6698 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6699 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6702 int meshDim(getStructuredMesh()->getMeshDimension());
6703 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6705 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6708 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6710 int meshDim(getStructuredMesh()->getMeshDimension());
6711 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6713 if((const DataArrayIdType *)_fam_cells)
6714 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_fam_cells->getNumberOfTuples()),ToMedIntArray(_fam_cells)->getConstPointer()));
6715 if((const DataArrayIdType *)_fam_faces)
6716 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_fam_faces->getNumberOfTuples()),ToMedIntArray(_fam_faces)->getConstPointer()));
6717 if((const DataArrayIdType *)_fam_nodes)
6718 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_fam_nodes->getNumberOfTuples()),ToMedIntArray(_fam_nodes)->getConstPointer()));
6719 if((const DataArrayIdType *)_num_cells)
6720 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_num_cells->getNumberOfTuples()),ToMedIntArray(_num_cells)->getConstPointer()));
6721 if((const DataArrayIdType *)_num_faces)
6722 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_num_faces->getNumberOfTuples()),ToMedIntArray(_num_faces)->getConstPointer()));
6723 if((const DataArrayIdType *)_num_nodes)
6724 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_num_nodes->getNumberOfTuples()),ToMedIntArray(_num_nodes)->getConstPointer()));
6725 if((const DataArrayAsciiChar *)_names_cells)
6727 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6729 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells 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_CELL,geoTypeReq,ToMedInt(_names_cells->getNumberOfTuples()),_names_cells->getConstPointer()));
6735 if((const DataArrayAsciiChar *)_names_faces)
6737 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6739 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6740 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6741 throw INTERP_KERNEL::Exception(oss.str().c_str());
6743 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_names_faces->getNumberOfTuples()),_names_faces->getConstPointer()));
6745 if((const DataArrayAsciiChar *)_names_nodes)
6747 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6749 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6750 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6751 throw INTERP_KERNEL::Exception(oss.str().c_str());
6753 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_names_nodes->getNumberOfTuples()),_names_nodes->getConstPointer()));
6756 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6760 * Returns an empty instance of MEDFileCMesh.
6761 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6762 * mesh using decrRef() as it is no more needed.
6764 MEDFileCMesh *MEDFileCMesh::New()
6766 return new MEDFileCMesh;
6770 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6771 * file. The first mesh in the file is loaded.
6772 * \param [in] fileName - the name of MED file to read.
6773 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6774 * mesh using decrRef() as it is no more needed.
6775 * \throw If the file is not readable.
6776 * \throw If there is no meshes in the file.
6777 * \throw If the mesh in the file is not a Cartesian one.
6779 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6781 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6782 return New(fid,mrs);
6785 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6787 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6791 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6792 * file. The mesh to load is specified by its name and numbers of a time step and an
6794 * \param [in] fileName - the name of MED file to read.
6795 * \param [in] mName - the name of the mesh to read.
6796 * \param [in] dt - the number of a time step.
6797 * \param [in] it - the number of an iteration.
6798 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6799 * mesh using decrRef() as it is no more needed.
6800 * \throw If the file is not readable.
6801 * \throw If there is no mesh with given attributes in the file.
6802 * \throw If the mesh in the file is not a Cartesian one.
6804 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6806 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6807 return New(fid,mName,dt,it,mrs);
6810 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6812 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6815 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6817 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6820 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6822 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6823 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6828 * Returns the dimension on cells in \a this mesh.
6829 * \return int - the mesh dimension.
6830 * \throw If there are no cells in this mesh.
6832 int MEDFileCMesh::getMeshDimension() const
6834 if(!((const MEDCouplingCMesh*)_cmesh))
6835 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6836 return _cmesh->getMeshDimension();
6840 * Returns the dimension on nodes in \a this mesh.
6841 * \return int - the space dimension.
6842 * \throw If there are no cells in this mesh.
6844 int MEDFileCMesh::getSpaceDimension() const
6846 if(!((const MEDCouplingCMesh*)_cmesh))
6847 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6848 return _cmesh->getSpaceDimension();
6852 * Returns a string describing \a this mesh.
6853 * \return std::string - the mesh information string.
6855 std::string MEDFileCMesh::simpleRepr() const
6857 return MEDFileStructuredMesh::simpleRepr();
6861 * Returns a full textual description of \a this mesh.
6862 * \return std::string - the string holding the mesh description.
6864 std::string MEDFileCMesh::advancedRepr() const
6866 return simpleRepr();
6869 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6871 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6875 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6877 return new MEDFileCMesh;
6880 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6882 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6883 ret->deepCpyEquivalences(*this);
6884 if((const MEDCouplingCMesh*)_cmesh)
6885 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6886 ret->deepCpyAttributes();
6891 * Checks if \a this and another mesh are equal.
6892 * \param [in] other - the mesh to compare with.
6893 * \param [in] eps - a precision used to compare real values.
6894 * \param [in,out] what - the string returning description of unequal data.
6895 * \return bool - \c true if the meshes are equal, \c false, else.
6897 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6899 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6901 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6904 what="Mesh types differ ! This is cartesian and other is NOT !";
6907 clearNonDiscrAttributes();
6908 otherC->clearNonDiscrAttributes();
6909 const MEDCouplingCMesh *coo1=_cmesh;
6910 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6911 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6913 what="Mismatch of cartesian meshes ! One is defined and not other !";
6918 bool ret=coo1->isEqual(coo2,eps);
6921 what="cartesian meshes differ !";
6929 * Clears redundant attributes of incorporated data arrays.
6931 void MEDFileCMesh::clearNonDiscrAttributes() const
6933 MEDFileStructuredMesh::clearNonDiscrAttributes();
6934 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6937 MEDFileCMesh::MEDFileCMesh()
6941 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6944 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6946 catch(INTERP_KERNEL::Exception& e)
6951 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6953 MEDCoupling::MEDCouplingMeshType meshType;
6956 MEDCoupling::MEDCouplingAxisType axType;
6957 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6958 if(meshType!=CARTESIAN)
6960 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6961 throw INTERP_KERNEL::Exception(oss.str().c_str());
6963 MEDFileCMeshL2 loaderl2;
6964 loaderl2.loadAll(fid,mid,mName,dt,it);
6965 setAxisType(axType);
6966 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6969 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6973 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6974 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6976 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6978 synchronizeTinyInfoOnLeaves();
6982 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6984 synchronizeTinyInfoOnLeaves();
6989 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6990 * \param [in] m - the new MEDCouplingCMesh to refer to.
6991 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6994 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6996 dealWithTinyInfo(m);
7002 MEDFileMesh *MEDFileCMesh::cartesianize() const
7004 if(getAxisType()==AX_CART)
7007 return const_cast<MEDFileCMesh *>(this);
7011 const MEDCouplingCMesh *cmesh(getMesh());
7013 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7014 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
7015 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
7016 clmesh->setCoords(coords);
7017 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
7018 ret->MEDFileStructuredMesh::operator=(*this);
7019 ret->setMesh(clmesh);
7020 ret->setAxisType(AX_CART);
7025 void MEDFileCMesh::writeMeshLL(med_idt fid) const
7027 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7028 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7029 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7030 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7031 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7032 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7033 int spaceDim(_cmesh->getSpaceDimension());
7034 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7035 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7036 for(int i=0;i<spaceDim;i++)
7038 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
7040 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7041 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
7042 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
7044 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7046 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7047 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
7048 for(int i=0;i<spaceDim;i++)
7050 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
7051 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,ToMedInt(da->getNumberOfTuples()),da->getConstPointer()));
7054 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7055 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7058 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
7060 const MEDCouplingCMesh *cmesh=_cmesh;
7063 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
7064 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
7065 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
7066 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
7069 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
7071 return new MEDFileCurveLinearMesh;
7074 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
7076 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
7079 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
7081 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7082 return New(fid,mrs);
7085 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7087 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7088 return New(fid,mName,dt,it,mrs);
7091 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7093 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
7096 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
7098 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
7101 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
7103 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
7104 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
7108 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
7110 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7114 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
7116 return new MEDFileCurveLinearMesh;
7119 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
7121 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7122 ret->deepCpyEquivalences(*this);
7123 if((const MEDCouplingCurveLinearMesh*)_clmesh)
7124 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
7125 ret->deepCpyAttributes();
7129 int MEDFileCurveLinearMesh::getMeshDimension() const
7131 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7132 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
7133 return _clmesh->getMeshDimension();
7136 std::string MEDFileCurveLinearMesh::simpleRepr() const
7138 return MEDFileStructuredMesh::simpleRepr();
7141 std::string MEDFileCurveLinearMesh::advancedRepr() const
7143 return simpleRepr();
7146 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7148 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7150 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
7153 what="Mesh types differ ! This is curve linear and other is NOT !";
7156 clearNonDiscrAttributes();
7157 otherC->clearNonDiscrAttributes();
7158 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
7159 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
7160 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7162 what="Mismatch of curve linear meshes ! One is defined and not other !";
7167 bool ret=coo1->isEqual(coo2,eps);
7170 what="curve linear meshes differ !";
7177 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
7179 MEDFileStructuredMesh::clearNonDiscrAttributes();
7180 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
7183 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
7185 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
7188 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
7189 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
7190 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
7191 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
7194 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
7196 synchronizeTinyInfoOnLeaves();
7200 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
7202 dealWithTinyInfo(m);
7208 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
7210 if(getAxisType()==AX_CART)
7213 return const_cast<MEDFileCurveLinearMesh *>(this);
7217 const MEDCouplingCurveLinearMesh *mesh(getMesh());
7219 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7220 const DataArrayDouble *coords(mesh->getCoords());
7222 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
7223 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7224 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
7225 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7226 mesh2->setCoords(coordsCart);
7227 ret->setMesh(mesh2);
7228 ret->setAxisType(AX_CART);
7233 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7235 synchronizeTinyInfoOnLeaves();
7239 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7243 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7246 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7248 catch(INTERP_KERNEL::Exception& e)
7253 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7255 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7256 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7257 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7258 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7259 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7260 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7261 int spaceDim=_clmesh->getSpaceDimension();
7262 int meshDim=_clmesh->getMeshDimension();
7263 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7264 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7265 const DataArrayDouble *coords=_clmesh->getCoords();
7267 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7268 for(int i=0;i<spaceDim;i++)
7270 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7272 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7273 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
7274 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
7276 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7278 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7279 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7280 std::vector<mcIdType> nodeGridSt=_clmesh->getNodeGridStructure();
7281 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,ToMedIntArray(nodeGridSt)->getConstPointer()));
7283 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,ToMedInt(coords->getNumberOfTuples()),coords->begin()));
7285 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7286 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7289 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7291 MEDCoupling::MEDCouplingMeshType meshType;
7294 MEDCoupling::MEDCouplingAxisType axType;
7295 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7296 setAxisType(axType);
7297 if(meshType!=CURVE_LINEAR)
7299 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7300 throw INTERP_KERNEL::Exception(oss.str().c_str());
7302 MEDFileCLMeshL2 loaderl2;
7303 loaderl2.loadAll(fid,mid,mName,dt,it);
7304 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7307 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7310 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7312 return new MEDFileMeshMultiTS;
7315 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7317 return new MEDFileMeshMultiTS(fid);
7320 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7322 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7326 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7328 return new MEDFileMeshMultiTS(fid,mName);
7331 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7333 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7334 return New(fid,mName);
7337 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7339 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7340 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7342 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7343 if((const MEDFileMesh *)*it)
7344 meshOneTs[i]=(*it)->deepCopy();
7345 ret->_mesh_one_ts=meshOneTs;
7349 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7351 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7354 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7356 std::vector<const BigMemoryObject *> ret;
7357 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7358 ret.push_back((const MEDFileMesh *)*it);
7362 std::string MEDFileMeshMultiTS::getName() const
7364 if(_mesh_one_ts.empty())
7365 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7366 return _mesh_one_ts[0]->getName();
7369 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7371 std::string oldName(getName());
7372 std::vector< std::pair<std::string,std::string> > v(1);
7373 v[0].first=oldName; v[0].second=newMeshName;
7377 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7380 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7382 MEDFileMesh *cur(*it);
7384 ret=cur->changeNames(modifTab) || ret;
7389 void MEDFileMeshMultiTS::cartesianizeMe()
7391 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7393 MEDFileMesh *cur(*it);
7396 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7402 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7404 if(_mesh_one_ts.empty())
7405 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7406 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7409 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7412 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7413 _mesh_one_ts.resize(1);
7414 mesh1TimeStep->incrRef();
7415 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7416 _mesh_one_ts[0]=mesh1TimeStep;
7419 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7421 if ( MEDFileMesh* m = getOneTimeStep() )
7422 return m->getJoints();
7427 * \brief Set Joints that are common to all time-stamps
7429 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7431 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7433 (*it)->setJoints( joints );
7437 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7439 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7440 if((*it).isNotNull())
7441 if((*it)->presenceOfStructureElements())
7446 void MEDFileMeshMultiTS::killStructureElements()
7448 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7449 if((*it).isNotNull())
7450 (*it)->killStructureElements();
7453 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7455 MEDFileJoints *joints(getJoints());
7456 bool jointsWritten(false);
7458 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7460 if ( jointsWritten )
7461 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7463 jointsWritten = true;
7465 (*it)->copyOptionsFrom(*this);
7466 (*it)->writeLL(fid);
7469 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7472 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7474 MEDFileJoints *joints(0);
7475 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7477 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7478 joints = getOneTimeStep()->getJoints();
7480 _mesh_one_ts.clear(); //for the moment to be improved
7481 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7484 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7488 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7491 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7494 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7495 throw INTERP_KERNEL::Exception(oss.str().c_str());
7498 MEDCoupling::MEDCouplingMeshType meshType;
7500 MEDCoupling::MEDCouplingAxisType dummy3;
7501 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7502 loadFromFile(fid,ms.front());
7504 catch(INTERP_KERNEL::Exception& e)
7509 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7512 loadFromFile(fid,mName);
7514 catch(INTERP_KERNEL::Exception& e)
7519 MEDFileMeshes *MEDFileMeshes::New()
7521 return new MEDFileMeshes;
7524 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7526 return new MEDFileMeshes(fid);
7529 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7531 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7535 void MEDFileMeshes::writeLL(med_idt fid) const
7537 checkConsistencyLight();
7538 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7540 (*it)->copyOptionsFrom(*this);
7541 (*it)->writeLL(fid);
7545 // MEDFileMeshes::writ checkConsistencyLight();
7547 int MEDFileMeshes::getNumberOfMeshes() const
7549 return (int)_meshes.size();
7552 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7554 return new MEDFileMeshesIterator(this);
7557 /** Return a borrowed reference (caller is not responsible) */
7558 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7560 if(i<0 || i>=(int)_meshes.size())
7562 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7563 throw INTERP_KERNEL::Exception(oss.str().c_str());
7565 return _meshes[i]->getOneTimeStep();
7568 /** Return a borrowed reference (caller is not responsible) */
7569 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7571 std::vector<std::string> ms=getMeshesNames();
7572 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7575 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7576 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7577 throw INTERP_KERNEL::Exception(oss.str().c_str());
7579 return getMeshAtPos((int)std::distance(ms.begin(),it));
7582 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7584 std::vector<std::string> ret(_meshes.size());
7586 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7588 const MEDFileMeshMultiTS *f=(*it);
7591 ret[i]=f->getName();
7595 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7596 throw INTERP_KERNEL::Exception(oss.str().c_str());
7602 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7605 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7607 MEDFileMeshMultiTS *cur(*it);
7609 ret=cur->changeNames(modifTab) || ret;
7614 void MEDFileMeshes::cartesianizeMe()
7616 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7618 MEDFileMeshMultiTS *cur(*it);
7620 cur->cartesianizeMe();
7624 void MEDFileMeshes::resize(int newSize)
7626 _meshes.resize(newSize);
7629 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7632 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7633 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7634 elt->setOneTimeStep(mesh);
7635 _meshes.push_back(elt);
7638 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7641 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7642 if(i>=(int)_meshes.size())
7643 _meshes.resize(i+1);
7644 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7645 elt->setOneTimeStep(mesh);
7649 void MEDFileMeshes::destroyMeshAtPos(int i)
7651 if(i<0 || i>=(int)_meshes.size())
7653 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7654 throw INTERP_KERNEL::Exception(oss.str().c_str());
7656 _meshes.erase(_meshes.begin()+i);
7659 void MEDFileMeshes::loadFromFile(med_idt fid)
7661 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7663 _meshes.resize(ms.size());
7664 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7665 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7668 MEDFileMeshes::MEDFileMeshes()
7672 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7677 catch(INTERP_KERNEL::Exception& /*e*/)
7681 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7683 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7685 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7686 if((const MEDFileMeshMultiTS *)*it)
7687 meshes[i]=(*it)->deepCopy();
7688 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7689 ret->_meshes=meshes;
7693 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7695 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7698 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7700 std::vector<const BigMemoryObject *> ret;
7701 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7702 ret.push_back((const MEDFileMeshMultiTS *)*it);
7706 std::string MEDFileMeshes::simpleRepr() const
7708 std::ostringstream oss;
7709 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7710 simpleReprWithoutHeader(oss);
7714 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7716 int nbOfMeshes=getNumberOfMeshes();
7717 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7718 std::vector<std::string> mns=getMeshesNames();
7719 for(int i=0;i<nbOfMeshes;i++)
7720 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7723 void MEDFileMeshes::checkConsistencyLight() const
7725 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7727 std::set<std::string> s;
7728 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7730 const MEDFileMeshMultiTS *elt=(*it);
7733 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7734 throw INTERP_KERNEL::Exception(oss.str().c_str());
7736 std::size_t sz=s.size();
7737 s.insert(std::string((*it)->getName()));
7740 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7741 throw INTERP_KERNEL::Exception(oss.str().c_str());
7746 bool MEDFileMeshes::presenceOfStructureElements() const
7748 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7749 if((*it).isNotNull())
7750 if((*it)->presenceOfStructureElements())
7755 void MEDFileMeshes::killStructureElements()
7757 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7758 if((*it).isNotNull())
7759 (*it)->killStructureElements();
7762 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7767 _nb_iter=ms->getNumberOfMeshes();
7771 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7775 MEDFileMesh *MEDFileMeshesIterator::nextt()
7777 if(_iter_id<_nb_iter)
7779 MEDFileMeshes *ms(_ms);
7781 return ms->getMeshAtPos(_iter_id++);
7789 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7791 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7792 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7794 if(geoType==MED_NO_GEOTYPE)
7795 return INTERP_KERNEL::NORM_ERROR;
7796 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7797 throw INTERP_KERNEL::Exception(oss.str());
7799 return typmai2[std::distance(typmai,pos)];
7802 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7810 case MED_NODE_ELEMENT:
7814 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7815 throw INTERP_KERNEL::Exception(oss.str());