1 // Copyright (C) 2007-2022 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 // From MEDLOader.cxx TU
39 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
40 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
41 extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE];
43 using namespace MEDCoupling;
45 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
47 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
49 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
53 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
55 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
56 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
58 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
59 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
60 ret+=(*it2).capacity();
62 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
63 ret+=(*it).first.capacity()+sizeof(mcIdType);
67 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
69 std::vector<const BigMemoryObject *> ret(1);
70 ret[0]=(const MEDFileEquivalences *)_equiv;
75 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
76 * file. The first mesh in the file is loaded.
77 * \param [in] fileName - the name of MED file to read.
78 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
79 * mesh using decrRef() as it is no more needed.
80 * \throw If the file is not readable.
81 * \throw If there is no meshes in the file.
82 * \throw If the mesh in the file is of a not supported type.
84 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
86 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
90 MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
92 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
95 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
96 throw INTERP_KERNEL::Exception(oss.str().c_str());
98 MEDCoupling::MEDCouplingMeshType meshType;
101 MEDCoupling::MEDCouplingAxisType dummy3;
102 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
103 MCAuto<MEDFileMesh> ret;
108 ret=MEDFileUMesh::New();
113 ret=MEDFileCMesh::New();
118 ret=MEDFileCurveLinearMesh::New();
123 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
124 throw INTERP_KERNEL::Exception(oss.str().c_str());
127 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
132 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
133 * file. The mesh to load is specified by its name and numbers of a time step and an
135 * \param [in] fileName - the name of MED file to read.
136 * \param [in] mName - the name of the mesh to read.
137 * \param [in] dt - the number of a time step.
138 * \param [in] it - the number of an iteration.
139 * \param [in] joints - the sub-domain joints to use instead of those that can be read
140 * from the MED file. Usually this joints are those just read by another iteration
141 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
142 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
143 * mesh using decrRef() as it is no more needed.
144 * \throw If the file is not readable.
145 * \throw If there is no mesh with given attributes in the file.
146 * \throw If the mesh in the file is of a not supported type.
148 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
150 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
151 return New(fid,mName,dt,it,mrs,joints);
154 MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
156 MEDCoupling::MEDCouplingMeshType meshType;
159 MEDCoupling::MEDCouplingAxisType dummy3;
160 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
161 MCAuto<MEDFileMesh> ret;
166 ret=MEDFileUMesh::New();
171 ret=MEDFileCMesh::New();
176 ret=MEDFileCurveLinearMesh::New();
181 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
182 throw INTERP_KERNEL::Exception(oss.str().c_str());
185 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
190 * Writes \a this mesh into an open MED file specified by its descriptor.
191 * \param [in] fid - the MED file descriptor.
192 * \throw If the mesh name is not set.
193 * \throw If the file is open for reading only.
194 * \throw If the writing mode == 1 and the same data is present in an existing file.
196 void MEDFileMesh::writeLL(med_idt fid) const
199 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
201 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
204 const MEDFileEquivalences *eqs(_equiv);
210 * Checks if \a this and another mesh are equal.
211 * \param [in] other - the mesh to compare with.
212 * \param [in] eps - a precision used to compare real values.
213 * \param [in,out] what - the string returning description of unequal data.
214 * \return bool - \c true if the meshes are equal, \c false, else.
216 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
218 if(_order!=other->_order)
220 what="Orders differ !";
223 if(_iteration!=other->_iteration)
225 what="Iterations differ !";
228 if(fabs(_time-other->_time)>eps)
230 what="Time values differ !";
233 if(_dt_unit!=other->_dt_unit)
235 what="Time units differ !";
238 if(_name!=other->_name)
240 what="Names differ !";
243 //univ_name has been ignored -> not a bug because it is a mutable attribute
244 if(_desc_name!=other->_desc_name)
246 what="Description names differ !";
249 if(!areGrpsEqual(other,what))
251 if(!areFamsEqual(other,what))
253 if(!areEquivalencesEqual(other,what))
258 void MEDFileMesh::setName(const std::string& name)
264 * Clears redundant attributes of incorporated data arrays.
266 void MEDFileMesh::clearNonDiscrAttributes() const
271 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
273 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
275 if((*it).first==_name)
285 * Copies data on groups and families from another mesh.
286 * \param [in] other - the mesh to copy the data from.
288 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
290 _groups=other._groups;
291 _families=other._families;
296 * This method clear all the groups in the map.
297 * So this method does not operate at all on arrays.
298 * So this method can lead to orphan families.
300 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
302 void MEDFileMesh::clearGrpMap()
308 * This method clear all the families in the map.
309 * So this method does not operate at all on arrays.
310 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
312 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
314 void MEDFileMesh::clearFamMap()
320 * This method clear all the families and groups in the map.
321 * So this method does not operate at all on arrays.
322 * As all groups and families entry will be removed after
323 * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object.
325 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
327 void MEDFileMesh::clearFamGrpMaps()
334 * Returns names of families constituting a group.
335 * \param [in] name - the name of the group of interest.
336 * \return std::vector<std::string> - a sequence of names of the families.
337 * \throw If the name of a nonexistent group is specified.
339 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
341 std::string oname(name);
342 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
343 if(it==_groups.end())
345 std::vector<std::string> grps=getGroupsNames();
346 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
347 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
348 throw INTERP_KERNEL::Exception(oss.str().c_str());
354 * Returns names of families constituting some groups.
355 * \param [in] grps - a sequence of names of groups of interest.
356 * \return std::vector<std::string> - a sequence of names of the families.
357 * \throw If a name of a nonexistent group is present in \a grps.
359 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
361 std::set<std::string> fams;
362 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
364 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
365 if(it2==_groups.end())
367 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
368 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
369 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
370 throw INTERP_KERNEL::Exception(oss.str().c_str());
372 fams.insert((*it2).second.begin(),(*it2).second.end());
374 std::vector<std::string> fams2(fams.begin(),fams.end());
379 * Returns ids of families constituting a group.
380 * \param [in] name - the name of the group of interest.
381 * \return std::vector<int> - sequence of ids of the families.
382 * \throw If the name of a nonexistent group is specified.
384 std::vector<mcIdType> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
386 std::string oname(name);
387 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
388 std::vector<std::string> grps=getGroupsNames();
389 if(it==_groups.end())
391 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
392 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
393 throw INTERP_KERNEL::Exception(oss.str().c_str());
395 return getFamiliesIds((*it).second);
399 * Sets names of families constituting a group. If data on families of this group is
400 * already present, it is overwritten. Every family in \a fams is checked, and if a
401 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
402 * \param [in] name - the name of the group of interest.
403 * \param [in] fams - a sequence of names of families constituting the group.
405 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
407 std::string oname(name);
409 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
411 std::map<std::string,mcIdType>::iterator it2=_families.find(*it1);
412 if(it2==_families.end())
418 * Sets families constituting a group. The families are specified by their ids.
419 * If a family name is not found by its id, an exception is thrown.
420 * If several families have same id, the first one in lexical order is taken.
421 * \param [in] name - the name of the group of interest.
422 * \param [in] famIds - a sequence of ids of families constituting the group.
423 * \throw If a family name is not found by its id.
425 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<mcIdType>& famIds)
427 std::string oname(name);
428 std::vector<std::string> fams(famIds.size());
430 for(std::vector<mcIdType>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
432 std::string name2=getFamilyNameGivenId(*it1);
439 * Returns names of groups including a given family.
440 * \param [in] name - the name of the family of interest.
441 * \return std::vector<std::string> - a sequence of names of groups including the family.
443 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
445 std::vector<std::string> ret;
446 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
448 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
451 ret.push_back((*it1).first);
459 * Adds an existing family to groups.
460 * \param [in] famName - a name of family to add to \a grps.
461 * \param [in] grps - a sequence of group names to add the family in.
462 * \throw If a family named \a famName not yet exists.
464 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
466 std::string fName(famName);
467 const std::map<std::string,mcIdType>::const_iterator it=_families.find(fName);
468 if(it==_families.end())
470 std::vector<std::string> fams=getFamiliesNames();
471 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
472 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
473 throw INTERP_KERNEL::Exception(oss.str().c_str());
475 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
477 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
478 if(it2!=_groups.end())
479 (*it2).second.push_back(fName);
482 std::vector<std::string> grps2(1,fName);
489 * Returns names of all groups of \a this mesh.
490 * \return std::vector<std::string> - a sequence of group names.
492 std::vector<std::string> MEDFileMesh::getGroupsNames() const
494 std::vector<std::string> ret(_groups.size());
496 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
502 * Returns names of all families of \a this mesh.
503 * \return std::vector<std::string> - a sequence of family names.
505 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
507 std::vector<std::string> ret(_families.size());
509 for(std::map<std::string, mcIdType >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
515 * Returns names of all families of \a this mesh but like they would be in file.
516 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
517 * This method is only useful for aggressive users that want to have in their file a same family lying both on cells and on nodes. This is not a good idea for lisibility !
518 * For your information internally in memory such families are renamed to have a nicer API.
520 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
522 std::vector<std::string> ret(getFamiliesNames());
523 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
528 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
529 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
530 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
533 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
535 std::vector<std::string> ret;
536 std::vector<std::string> allGrps(getGroupsNames());
537 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
539 std::vector<mcIdType> levs(getGrpNonEmptyLevelsExt((*it)));
540 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
547 * Returns all relative mesh levels (including nodes) where a given group is defined.
548 * \param [in] grp - the name of the group of interest.
549 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
551 std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
553 std::vector<std::string> fams(getFamiliesOnGroup(grp));
554 return getFamsNonEmptyLevelsExt(fams);
558 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
559 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
560 * \param [in] grps - a sequence of names of the groups of interest.
561 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
563 std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
565 std::vector<std::string> fams(getFamiliesOnGroups(grps));
566 return getFamsNonEmptyLevels(fams);
570 * Returns all relative mesh levels (including nodes) where given groups are defined.
571 * \param [in] grps - a sequence of names of the groups of interest.
572 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
574 std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
576 std::vector<std::string> fams(getFamiliesOnGroups(grps));
577 return getFamsNonEmptyLevelsExt(fams);
581 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
582 * To include nodes, call getGrpNonEmptyLevelsExt() method.
583 * \param [in] grp - the name of the group of interest.
584 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
586 std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
588 std::vector<std::string> fams(getFamiliesOnGroup(grp));
589 return getFamsNonEmptyLevels(fams);
593 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
594 * To include nodes, call getFamNonEmptyLevelsExt() method.
595 * \param [in] fam - the name of the family of interest.
596 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
598 std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
600 std::vector<std::string> fams(1,std::string(fam));
601 return getFamsNonEmptyLevels(fams);
605 * Returns all relative mesh levels (including nodes) where a given family is defined.
606 * \param [in] fam - the name of the family of interest.
607 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
609 std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
611 std::vector<std::string> fams(1,std::string(fam));
612 return getFamsNonEmptyLevelsExt(fams);
615 std::string MEDFileMesh::GetMagicFamilyStr()
617 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
621 * Changes a name of every family, included in one group only, to be same as the group name.
622 * \throw If there are families with equal names in \a this mesh.
624 void MEDFileMesh::assignFamilyNameWithGroupName()
626 std::map<std::string, std::vector<std::string> > groups(_groups);
627 std::map<std::string,mcIdType> newFams;
628 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
630 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
631 if(grps.size()==1 && groups[grps[0]].size()==1)
633 if(newFams.find(grps[0])!=newFams.end())
635 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
636 throw INTERP_KERNEL::Exception(oss.str().c_str());
638 newFams[grps[0]]=(*it).second;
639 std::vector<std::string>& grps2=groups[grps[0]];
640 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
645 if(newFams.find((*it).first)!=newFams.end())
647 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
648 throw INTERP_KERNEL::Exception(oss.str().c_str());
650 newFams[(*it).first]=(*it).second;
658 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
660 * \return the removed groups.
662 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
664 std::vector<std::string> ret;
665 std::map<std::string, std::vector<std::string> > newGrps;
666 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
668 if((*it).second.empty())
669 ret.push_back((*it).first);
671 newGrps[(*it).first]=(*it).second;
678 void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name)
680 std::map<std::string, std::vector<std::string> >::iterator it(_groups.find(name));
681 std::vector<std::string> grps(getGroupsNames());
682 if(it==_groups.end())
684 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
685 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
686 throw INTERP_KERNEL::Exception(oss.str().c_str());
688 const std::vector<std::string> &famsOnGrp((*it).second);
689 std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(name));
690 const DataArrayIdType *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt));
693 MCAuto<DataArrayIdType> vals(famArr->getDifferentValues());
694 MCAuto<DataArrayIdType> famIds2(DataArrayIdType::NewFromStdVector(famIds));
695 MCAuto<DataArrayIdType> idsToKill(famIds2->buildIntersection(vals));
696 if(idsToKill->empty())
698 std::vector<std::string> newFamsOnGrp;
699 for(std::vector<std::string>::const_iterator itt=famsOnGrp.begin();itt!=famsOnGrp.end();itt++)
701 if(!idsToKill->presenceOfValue(getFamilyId(*itt)))
702 newFamsOnGrp.push_back(*itt);
704 (*it).second=newFamsOnGrp;
708 * Removes a group from \a this mesh.
709 * \param [in] name - the name of the group to remove.
710 * \throw If no group with such a \a name exists.
712 void MEDFileMesh::removeGroup(const std::string& name)
714 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(name);
715 std::vector<std::string> grps(getGroupsNames());
716 if(it==_groups.end())
718 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
719 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
720 throw INTERP_KERNEL::Exception(oss.str().c_str());
726 * Removes a family from \a this mesh.
727 * \param [in] name - the name of the family to remove.
728 * \throw If no family with such a \a name exists.
730 void MEDFileMesh::removeFamily(const std::string& name)
732 std::string oname(name);
733 std::map<std::string, mcIdType >::iterator it=_families.find(oname);
734 std::vector<std::string> fams=getFamiliesNames();
735 if(it==_families.end())
737 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
738 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
739 throw INTERP_KERNEL::Exception(oss.str().c_str());
742 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
744 std::vector<std::string>& v=(*it3).second;
745 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
752 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
753 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
754 * family field whatever its level. This method also suppresses the orphan families.
756 * \return - The list of removed groups names.
758 * \sa MEDFileMesh::removeOrphanFamilies.
760 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
762 removeOrphanFamilies();
763 return removeEmptyGroups();
767 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
768 * 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.
770 * \return - The list of removed families names.
771 * \sa MEDFileMesh::removeOrphanGroups , MEDFileMesh::removeFamiliesReferedByNoGroups
773 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
775 MCAuto<DataArrayIdType> allFamIdsInUse=computeAllFamilyIdsInUse();
776 std::vector<std::string> ret;
777 if(!((DataArrayIdType*)allFamIdsInUse))
779 ret=getFamiliesNames();
780 _families.clear(); _groups.clear();
783 std::map<std::string,mcIdType> famMap;
784 std::map<std::string, std::vector<std::string> > grps(_groups);
785 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
787 if(allFamIdsInUse->presenceOfValue((*it).second))
788 famMap[(*it).first]=(*it).second;
791 ret.push_back((*it).first);
792 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
793 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
795 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
796 std::vector<std::string>& famv=(*it3).second;
797 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
803 { _families=famMap; _groups=grps; }
808 * 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
809 * this family is orphan or not.
811 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
812 * \sa MEDFileMesh::removeOrphanFamilies
814 void MEDFileMesh::removeFamiliesReferedByNoGroups()
816 std::map<std::string,mcIdType> fams;
817 std::set<std::string> sfams;
818 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
819 sfams.insert((*it).first);
820 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
821 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
823 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
824 if(*it!=DFT_FAM_NAME)
825 _families.erase(*it);
829 * 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
830 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
831 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
833 * 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.
835 * \sa MEDFileMesh::removeOrphanFamilies, MEDFileMesh::zipFamilies
837 void MEDFileMesh::rearrangeFamilies()
839 checkOrphanFamilyZero();
840 removeFamiliesReferedByNoGroups();
842 std::vector<int> levels(getNonEmptyLevelsExt());
843 std::set<mcIdType> idsRefed;
844 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
846 idsRefed.insert((*it).second);
849 if(!getGroupsOnFamily((*it).first).empty())
851 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 !";
852 throw INTERP_KERNEL::Exception(oss.str());
856 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
858 const DataArrayIdType *fams(0);
861 fams=getFamilyFieldAtLevel(*it);
863 catch(INTERP_KERNEL::Exception& ) { }
866 std::vector<bool> v(fams->getNumberOfTuples(),false);
867 for(std::set<mcIdType>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
868 fams->switchOnTupleEqualTo(*pt,v);
869 MCAuto<DataArrayIdType> unfetchedIds(DataArrayIdType::BuildListOfSwitchedOff(v));
870 if(!unfetchedIds->empty())
872 MCAuto<DataArrayIdType> newFams(fams->deepCopy());
873 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
874 setFamilyFieldArr(*it,newFams);
877 removeOrphanFamilies();
881 * This method has no impact on existing groups. This method has only impact on families behind the groups.
882 * 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.
883 * 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
884 * having the name of the first family appearing in family definition and with the corresponding family ID.
886 void MEDFileMesh::zipFamilies()
888 checkOrphanFamilyZero();
889 removeFamiliesReferedByNoGroups();
890 std::map< std::set<std::string> , std::vector<std::string> > setOfFamilies;
891 // firstly, store in setOfFamilies as key the common set of groups, and as value the families having such same set of groups
892 for(auto fam : _families)
894 std::vector<std::string> grps( this->getGroupsOnFamily( fam.first ) );
895 std::set<std::string> sgrps(grps.begin(),grps.end());
896 setOfFamilies[sgrps].push_back(fam.first);
899 std::map<std::string, std::vector<std::string> > newGroups(_groups);
900 std::map<std::string,mcIdType> newFams(_families);
901 std::vector<int> levels(getNonEmptyLevelsExt());
902 std::map<mcIdType, std::vector<mcIdType> > famIdsToSubstitute;
903 // iterate on all different set of groups
904 std::set<std::string> familiesToKill;
905 for(auto setOfCommonGrp : setOfFamilies)
907 if( setOfCommonGrp.second.size()<=1 )
909 for(auto fam=setOfCommonGrp.second.begin()+1 ; fam != setOfCommonGrp.second.end() ; fam++)
910 familiesToKill.insert(*fam);
912 // iterate on all different set of groups
913 for(auto setOfCommonGrp : setOfFamilies)
915 if( setOfCommonGrp.second.size()<=1 )
917 std::string newFamName(setOfCommonGrp.second[0]);
918 auto newFamID(_families[newFamName]);
919 for(auto grpToBeModified : setOfCommonGrp.first)
921 std::vector<std::string> newFamiliesForCurGrp(1,newFamName);
922 const std::vector<std::string>& familiesOnCurGrp(_groups[grpToBeModified]);
923 const std::vector<std::string>& familiesToZip(setOfCommonGrp.second);
924 std::for_each(familiesToZip.begin(),familiesToZip.end(),[&famIdsToSubstitute,this,newFamID](const std::string& elt) { famIdsToSubstitute[newFamID].push_back(this->getFamilyId(elt)); });
925 // for each family shared by the current group only keep those not sharing setOfCommonGrp.second
926 std::for_each(familiesOnCurGrp.begin(),familiesOnCurGrp.end(),[&familiesToKill,&newFamiliesForCurGrp](const std::string& elt)
927 { if( familiesToKill.find(elt) == familiesToKill.end() ) { newFamiliesForCurGrp.push_back(elt); } });
928 newGroups[grpToBeModified] = newFamiliesForCurGrp;
930 for(auto familyToKill = setOfCommonGrp.second.begin()+1 ; familyToKill != setOfCommonGrp.second.end(); ++familyToKill)
932 newFams.erase( newFams.find(*familyToKill) );
936 // apply modifications in datastructure
937 for(auto famIdsSubstSession : famIdsToSubstitute)
939 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
941 DataArrayIdType *fams(nullptr);
944 fams=getFamilyFieldAtLevel(*it);
946 catch(INTERP_KERNEL::Exception& ) { }
949 MCAuto<DataArrayIdType> idsToModif(fams->findIdsEqualList(famIdsSubstSession.second.data(),famIdsSubstSession.second.data()+famIdsSubstSession.second.size()));
950 fams->setPartOfValuesSimple3(famIdsSubstSession.first,idsToModif->begin(),idsToModif->end(),0,1,1);
958 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
960 void MEDFileMesh::checkOrphanFamilyZero() const
962 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
964 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
966 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
967 throw INTERP_KERNEL::Exception(oss.str().c_str());
973 * Renames a group in \a this mesh.
974 * \param [in] oldName - a current name of the group to rename.
975 * \param [in] newName - a new group name.
976 * \throw If no group named \a oldName exists in \a this mesh.
977 * \throw If a group named \a newName already exists.
979 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
981 std::string oname(oldName);
982 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
983 std::vector<std::string> grps=getGroupsNames();
984 if(it==_groups.end())
986 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
987 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
988 throw INTERP_KERNEL::Exception(oss.str().c_str());
990 std::string nname(newName);
991 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
992 if(it2!=_groups.end())
994 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
995 throw INTERP_KERNEL::Exception(oss.str().c_str());
997 std::vector<std::string> cpy=(*it).second;
999 _groups[newName]=cpy;
1003 * Changes an id of a family in \a this mesh.
1004 * This method calls changeFamilyIdArr().
1005 * \param [in] oldId - a current id of the family.
1006 * \param [in] newId - a new family id.
1008 void MEDFileMesh::changeFamilyId(mcIdType oldId, mcIdType newId)
1010 changeFamilyIdArr(oldId,newId);
1011 std::map<std::string,mcIdType> fam2;
1012 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1014 if((*it).second==oldId)
1015 fam2[(*it).first]=newId;
1017 fam2[(*it).first]=(*it).second;
1023 * Renames a family in \a this mesh.
1024 * \param [in] oldName - a current name of the family to rename.
1025 * \param [in] newName - a new family name.
1026 * \throw If no family named \a oldName exists in \a this mesh.
1027 * \throw If a family named \a newName already exists.
1029 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
1031 std::string oname(oldName);
1032 std::map<std::string, mcIdType >::iterator it=_families.find(oname);
1033 std::vector<std::string> fams=getFamiliesNames();
1034 if(it==_families.end())
1036 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
1037 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1038 throw INTERP_KERNEL::Exception(oss.str().c_str());
1040 std::string nname(newName);
1041 std::map<std::string, mcIdType >::iterator it2=_families.find(nname);
1042 if(it2!=_families.end())
1044 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
1045 throw INTERP_KERNEL::Exception(oss.str().c_str());
1047 mcIdType cpy=(*it).second;
1048 _families.erase(it);
1049 _families[newName]=cpy;
1050 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
1052 std::vector<std::string>& v=(*it3).second;
1053 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
1060 * Checks if \a this and another mesh contains the same families.
1061 * \param [in] other - the mesh to compare with \a this one.
1062 * \param [in,out] what - an unused parameter.
1063 * \return bool - \c true if number of families and their ids are the same in the two
1064 * meshes. Families with the id == \c 0 are not considered.
1066 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
1068 if(_families==other->_families)
1070 std::map<std::string,mcIdType> fam0;
1071 std::map<std::string,mcIdType> fam1;
1072 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1074 fam0[(*it).first]=(*it).second;
1075 for(std::map<std::string,mcIdType>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
1077 fam1[(*it).first]=(*it).second;
1082 * Checks if \a this and another mesh contains the same groups.
1083 * \param [in] other - the mesh to compare with \a this one.
1084 * \param [in,out] what - a string describing a difference of groups of the two meshes
1085 * in case if this method returns \c false.
1086 * \return bool - \c true if number of groups and families constituting them are the
1087 * same in the two meshes.
1089 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
1091 if(_groups==other->_groups)
1094 std::size_t sz=_groups.size();
1095 if(sz!=other->_groups.size())
1097 what="Groups differ because not same number !\n";
1102 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
1103 for(std::size_t i=0;i<sz && ret;i++,it1++)
1105 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
1106 if(it2!=other->_groups.end())
1108 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
1109 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1115 what="A group in first mesh exists not in other !\n";
1121 std::ostringstream oss; oss << "Groups description differs :\n";
1122 oss << "First group description :\n";
1123 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1125 oss << " Group \"" << (*it).first << "\" on following families :\n";
1126 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1127 oss << " \"" << *it2 << "\n";
1129 oss << "Second group description :\n";
1130 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1132 oss << " Group \"" << (*it).first << "\" on following families :\n";
1133 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1134 oss << " \"" << *it2 << "\n";
1142 * Checks if a group with a given name exists in \a this mesh.
1143 * \param [in] groupName - the group name.
1144 * \return bool - \c true the group \a groupName exists in \a this mesh.
1146 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1148 std::string grpName(groupName);
1149 return _groups.find(grpName)!=_groups.end();
1153 * Checks if a family with a given id exists in \a this mesh.
1154 * \param [in] famId - the family id.
1155 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1157 bool MEDFileMesh::existsFamily(mcIdType famId) const
1159 for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1160 if((*it2).second==famId)
1166 * Checks if a family with a given name exists in \a this mesh.
1167 * \param [in] familyName - the family name.
1168 * \return bool - \c true the family \a familyName exists in \a this mesh.
1170 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1172 std::string fname(familyName);
1173 return _families.find(fname)!=_families.end();
1177 * Sets an id of a family.
1178 * \param [in] familyName - the family name.
1179 * \param [in] id - a new id of the family.
1181 void MEDFileMesh::setFamilyId(const std::string& familyName, mcIdType id)
1183 std::string fname(familyName);
1184 _families[fname]=id;
1187 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, mcIdType id)
1189 std::string fname(familyName);
1190 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1191 if((*it).second==id)
1193 if((*it).first!=familyName)
1195 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1196 throw INTERP_KERNEL::Exception(oss.str().c_str());
1199 _families[fname]=id;
1203 * Adds a family to \a this mesh.
1204 * \param [in] familyName - a name of the family.
1205 * \param [in] famId - an id of the family.
1206 * \throw If a family with the same name or id already exists in \a this mesh.
1208 void MEDFileMesh::addFamily(const std::string& familyName, mcIdType famId)
1210 std::string fname(familyName);
1211 std::map<std::string,mcIdType>::const_iterator it=_families.find(fname);
1212 if(it==_families.end())
1214 for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1215 if((*it2).second==famId)
1217 std::ostringstream oss;
1218 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1219 throw INTERP_KERNEL::Exception(oss.str().c_str());
1221 _families[fname]=famId;
1225 if((*it).second!=famId)
1227 std::ostringstream oss;
1228 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1229 throw INTERP_KERNEL::Exception(oss.str().c_str());
1235 * Creates a group including all mesh entities of given dimension.
1236 * \warning This method does \b not guarantee that the created group includes mesh
1237 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1238 * present in family fields of different dimensions. To assure this, call
1239 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1240 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1242 * \param [in] groupName - a name of the new group.
1243 * \throw If a group named \a groupName already exists.
1244 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1245 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1247 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1249 std::string grpName(groupName);
1250 std::vector<int> levs=getNonEmptyLevelsExt();
1251 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1253 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1254 oss << "Available relative ext levels are : ";
1255 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1256 throw INTERP_KERNEL::Exception(oss.str().c_str());
1258 if(existsGroup(groupName))
1260 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1261 oss << "Already existing groups are : ";
1262 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1263 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1264 throw INTERP_KERNEL::Exception(oss.str().c_str());
1266 const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1268 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1269 MCAuto<DataArrayIdType> famIds=fieldFamIds->getDifferentValues();
1270 std::vector<std::string> familiesOnWholeGroup;
1271 for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
1274 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1276 _groups[grpName]=familiesOnWholeGroup;
1280 * Ensures that given family ids do not present in family fields of dimensions different
1281 * than given ones. If a family id is present in the family fields of dimensions different
1282 * than the given ones, a new family is created and the whole data is updated accordingly.
1283 * \param [in] famIds - a sequence of family ids to check.
1284 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1285 * famIds should exclusively belong.
1286 * \return bool - \c true if no modification is done in \a this mesh by this method.
1288 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<mcIdType>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1290 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1291 std::vector<int> levs=getNonEmptyLevelsExt();
1292 std::set<int> levs2(levs.begin(),levs.end());
1293 std::vector<int> levsToTest;
1294 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1295 std::set<mcIdType> famIds2(famIds.begin(),famIds.end());
1297 mcIdType maxFamId=1;
1298 if(!_families.empty())
1299 maxFamId=getMaxFamilyId()+1;
1300 std::vector<std::string> allFams=getFamiliesNames();
1301 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1303 const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(*it);
1306 MCAuto<DataArrayIdType> famIds3=fieldFamIds->getDifferentValues();
1307 std::vector<mcIdType> tmp;
1308 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<mcIdType> >(tmp));
1309 for(std::vector<mcIdType>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1312 std::string famName=getFamilyNameGivenId(*it2);
1313 std::ostringstream oss; oss << "Family_" << maxFamId;
1314 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1315 addFamilyOnAllGroupsHaving(famName,zeName);
1316 _families[zeName]=maxFamId;
1317 (const_cast<DataArrayIdType *>(fieldFamIds))->changeValue(*it2,maxFamId);
1326 * Adds a family to a given group in \a this mesh. If the group with a given name does
1327 * not exist, it is created.
1328 * \param [in] grpName - the name of the group to add the family in.
1329 * \param [in] famName - the name of the family to add to the group named \a grpName.
1330 * \throw If \a grpName or \a famName is an empty string.
1331 * \throw If no family named \a famName is present in \a this mesh.
1333 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1335 std::string grpn(grpName);
1336 std::string famn(famName);
1337 if(grpn.empty() || famn.empty())
1338 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1339 std::vector<std::string> fams=getFamiliesNames();
1340 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1342 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1343 oss << "Create this family or choose an existing one ! Existing fams are : ";
1344 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1345 throw INTERP_KERNEL::Exception(oss.str().c_str());
1347 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1348 if(it==_groups.end())
1350 _groups[grpn].push_back(famn);
1354 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1355 if(it2==(*it).second.end())
1356 (*it).second.push_back(famn);
1361 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1362 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1363 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1365 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1367 std::string famNameCpp(famName);
1368 std::string otherCpp(otherFamName);
1369 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1371 std::vector<std::string>& v=(*it).second;
1372 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1374 v.push_back(otherCpp);
1379 void MEDFileMesh::checkNoGroupClash(const DataArrayIdType *famArr, const std::string& grpName) const
1381 std::vector<std::string> grpsNames(getGroupsNames());
1382 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
1384 std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(grpName));
1385 if(famArr->presenceOfValue(famIds))
1387 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
1388 throw INTERP_KERNEL::Exception(oss.str().c_str());
1393 * \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).
1394 * \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)
1396 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayIdType *ids, DataArrayIdType *famArr)
1399 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1400 std::string grpName(ids->getName());
1402 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1403 ids->checkStrictlyMonotonic(true);
1404 checkNoGroupClash(famArr,grpName);
1405 MCAuto<DataArrayIdType> famArrTmp; famArrTmp.takeRef(famArr);
1406 std::list< MCAuto<DataArrayIdType> > allFamIds(getAllNonNullFamilyIds());
1407 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1408 MCAuto<DataArrayIdType> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1409 MCAuto<DataArrayIdType> diffFamIds=famIds->getDifferentValues();
1410 std::vector<mcIdType> familyIds;
1411 std::vector< MCAuto<DataArrayIdType> > idsPerfamiliyIds;
1412 mcIdType maxVal=getTheMaxAbsFamilyId()+1;
1413 std::map<std::string,mcIdType> families(_families);
1414 std::map<std::string, std::vector<std::string> > groups(_groups);
1415 std::vector<std::string> fams;
1416 bool created(false);
1417 for(const mcIdType *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1419 MCAuto<DataArrayIdType> ids2Tmp=famIds->findIdsEqual(*famId);
1420 MCAuto<DataArrayIdType> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1421 MCAuto<DataArrayIdType> ids1=famArr->findIdsEqual(*famId);
1422 MCAuto<DataArrayIdType> ret0(ids1->buildSubstractionOptimized(ids2));
1425 bool isFamPresent=false;
1426 for(std::list< MCAuto<DataArrayIdType> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1427 isFamPresent=(*itl)->presenceOfValue(*famId);
1428 if(!isFamPresent && *famId!=0)
1429 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1432 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1433 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1434 fams.push_back(locFamName);
1435 if(existsFamily(*famId))
1437 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1438 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1441 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1445 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1446 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1447 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1448 if(existsFamily(*famId))
1450 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1451 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1456 for(std::size_t i=0;i<familyIds.size();i++)
1458 DataArrayIdType *da=idsPerfamiliyIds[i];
1459 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1462 std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
1463 if(itt!=groups.end())
1465 std::vector<std::string>& famsOnGrp((*itt).second);
1466 famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
1469 groups[grpName]=fams;
1473 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1475 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1478 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1480 std::string fam(familyNameToChange);
1481 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1483 std::vector<std::string>& fams((*it).second);
1484 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1488 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1494 * Returns a name of the family having a given id or, if no such a family exists, creates
1495 * a new uniquely named family and returns its name.
1496 * \param [in] id - the id of the family whose name is required.
1497 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1498 * \return std::string - the name of the existing or the created family.
1499 * \throw If it is not possible to create a unique family name.
1501 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(mcIdType id, bool& created)
1503 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1507 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1508 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1509 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1510 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1512 * This method will throws an exception if it is not possible to create a unique family name.
1514 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,mcIdType>& families, mcIdType id, bool& created)
1516 std::vector<std::string> famAlreadyExisting(families.size());
1518 for(std::map<std::string,mcIdType>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1520 if((*it).second!=id)
1522 famAlreadyExisting[ii]=(*it).first;
1531 std::ostringstream oss; oss << "Family_" << id;
1532 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1538 * Sets names and ids of all families in \a this mesh.
1539 * \param [in] info - a map of a family name to a family id.
1541 void MEDFileMesh::setFamilyInfo(const std::map<std::string,mcIdType>& info)
1547 * Sets names of all groups and families constituting them in \a this mesh.
1548 * \param [in] info - a map of a group name to a vector of names of families
1549 * constituting the group.
1551 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1557 * Returns an id of the family having a given name.
1558 * \param [in] name - the name of the family of interest.
1559 * \return mcIdType - the id of the family of interest.
1560 * \throw If no family with such a \a name exists.
1562 mcIdType MEDFileMesh::getFamilyId(const std::string& name) const
1564 std::map<std::string, mcIdType>::const_iterator it=_families.find(name);
1565 if(it==_families.end())
1567 std::vector<std::string> fams(getFamiliesNames());
1568 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1569 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1570 throw INTERP_KERNEL::Exception(oss.str().c_str());
1572 return (*it).second;
1576 * Returns ids of the families having given names.
1577 * \param [in] fams - a sequence of the names of families of interest.
1578 * \return std::vector<mcIdType> - a sequence of the ids of families of interest.
1579 * \throw If \a fams contains a name of an inexistent family.
1581 std::vector<mcIdType> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1583 std::vector<mcIdType> ret(fams.size());
1585 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1587 std::map<std::string, mcIdType>::const_iterator it2=_families.find(*it);
1588 if(it2==_families.end())
1590 std::vector<std::string> fams2=getFamiliesNames();
1591 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1592 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1593 throw INTERP_KERNEL::Exception(oss.str().c_str());
1595 ret[i]=(*it2).second;
1601 * Returns a maximal abs(id) of families in \a this mesh.
1602 * \return mcIdType - the maximal norm of family id.
1603 * \throw If there are no families in \a this mesh.
1605 mcIdType MEDFileMesh::getMaxAbsFamilyId() const
1607 if(_families.empty())
1608 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1609 mcIdType ret=-std::numeric_limits<mcIdType>::max();
1610 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1612 ret=std::max(std::abs((*it).second),ret);
1618 * Returns a maximal id of families in \a this mesh.
1619 * \return mcIdType - the maximal family id.
1620 * \throw If there are no families in \a this mesh.
1622 mcIdType MEDFileMesh::getMaxFamilyId() const
1624 if(_families.empty())
1625 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1626 mcIdType ret=-std::numeric_limits<mcIdType>::max();
1627 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1629 ret=std::max((*it).second,ret);
1635 * Returns a minimal id of families in \a this mesh.
1636 * \return mcIdType - the minimal family id.
1637 * \throw If there are no families in \a this mesh.
1639 mcIdType MEDFileMesh::getMinFamilyId() const
1641 if(_families.empty())
1642 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1643 mcIdType ret=std::numeric_limits<mcIdType>::max();
1644 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1646 ret=std::min((*it).second,ret);
1652 * Returns a maximal id of families in \a this mesh. Not only named families are
1653 * considered but all family fields as well.
1654 * \return mcIdType - the maximal family id.
1656 mcIdType MEDFileMesh::getTheMaxAbsFamilyId() const
1658 mcIdType m1=-std::numeric_limits<mcIdType>::max();
1659 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1660 m1=std::max(std::abs((*it).second),m1);
1661 mcIdType m2=getMaxAbsFamilyIdInArrays();
1662 return std::max(m1,m2);
1666 * Returns a maximal id of families in \a this mesh. Not only named families are
1667 * considered but all family fields as well.
1668 * \return mcIdType - the maximal family id.
1670 mcIdType MEDFileMesh::getTheMaxFamilyId() const
1672 mcIdType m1=-std::numeric_limits<mcIdType>::max();
1673 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1674 m1=std::max((*it).second,m1);
1675 mcIdType m2=getMaxFamilyIdInArrays();
1676 return std::max(m1,m2);
1680 * Returns a minimal id of families in \a this mesh. Not only named families are
1681 * considered but all family fields as well.
1682 * \return mcIdType - the minimal family id.
1684 mcIdType MEDFileMesh::getTheMinFamilyId() const
1686 mcIdType m1=std::numeric_limits<mcIdType>::max();
1687 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1688 m1=std::min((*it).second,m1);
1689 mcIdType m2=getMinFamilyIdInArrays();
1690 return std::min(m1,m2);
1694 * This method only considers the maps. The contain of family array is ignored here.
1696 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1698 DataArrayIdType *MEDFileMesh::getAllFamiliesIdsReferenced() const
1700 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
1701 std::set<mcIdType> v;
1702 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1703 v.insert((*it).second);
1704 ret->alloc((mcIdType)v.size(),1);
1705 std::copy(v.begin(),v.end(),ret->getPointer());
1710 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1712 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1714 DataArrayIdType *MEDFileMesh::computeAllFamilyIdsInUse() const
1716 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1717 MCAuto<DataArrayIdType> ret;
1718 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1720 const DataArrayIdType *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1721 MCAuto<DataArrayIdType> dv=arr->getDifferentValues();
1722 if((DataArrayIdType *) ret)
1723 ret=dv->buildUnion(ret);
1731 * true is returned if no modification has been needed. false if family
1732 * renumbering has been needed.
1734 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1736 std::vector<int> levs=getNonEmptyLevelsExt();
1737 std::set<mcIdType> allFamIds;
1738 mcIdType maxId=getMaxFamilyId()+1;
1739 std::map<int,std::vector<mcIdType> > famIdsToRenum;
1740 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1742 const DataArrayIdType *fam=getFamilyFieldAtLevel(*it);
1745 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1746 std::set<mcIdType> r2;
1747 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1749 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1750 std::set<mcIdType> r3;
1751 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1754 if(famIdsToRenum.empty())
1756 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1757 for(std::map<int,std::vector<mcIdType> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1759 DataArrayIdType *fam=const_cast<DataArrayIdType *>(getFamilyFieldAtLevel((*it2).first));
1760 mcIdType *famIdsToChange=fam->getPointer();
1761 std::map<mcIdType,mcIdType> ren;
1762 for(std::vector<mcIdType>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1764 if(allIds->presenceOfValue(*it3))
1766 std::string famName=getFamilyNameGivenId(*it3);
1767 std::vector<std::string> grps=getGroupsOnFamily(famName);
1770 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1771 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1772 addFamilyOnGrp((*it4),newFam);
1775 MCAuto<DataArrayIdType> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1776 for(const mcIdType *id=ids->begin();id!=ids->end();id++)
1777 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1783 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1784 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1785 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1786 * This method will throw an exception if a same family id is detected in different level.
1787 * \warning This policy is the opposite of those in MED file documentation ...
1789 void MEDFileMesh::normalizeFamIdsTrio()
1791 ensureDifferentFamIdsPerLevel();
1792 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1793 std::vector<int> levs=getNonEmptyLevelsExt();
1794 std::set<int> levsS(levs.begin(),levs.end());
1795 std::set<std::string> famsFetched;
1796 std::map<std::string,mcIdType> families;
1797 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1800 const DataArrayIdType *fam=getFamilyFieldAtLevel(0);
1804 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1805 std::map<mcIdType,mcIdType> ren;
1806 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
1808 mcIdType nbOfTuples=fam->getNumberOfTuples();
1809 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1810 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1812 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1814 if(allIds->presenceOfValue(*it))
1816 std::string famName=getFamilyNameGivenId(*it);
1817 families[famName]=ren[*it];
1818 famsFetched.insert(famName);
1823 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1826 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
1830 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1831 std::map<mcIdType,mcIdType> ren;
1832 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
1834 mcIdType nbOfTuples=fam->getNumberOfTuples();
1835 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1836 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1838 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1840 if(allIds->presenceOfValue(*it))
1842 std::string famName=getFamilyNameGivenId(*it);
1843 families[famName]=ren[*it];
1844 famsFetched.insert(famName);
1849 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1851 DataArrayIdType *fam=const_cast<DataArrayIdType*>(getFamilyFieldAtLevel(*it2));
1854 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1855 fam->fillWithZero();
1856 for(const mcIdType *it3=tmp->begin();it3!=tmp->end();it3++)
1857 if(allIds->presenceOfValue(*it3))
1859 std::string famName=getFamilyNameGivenId(*it3);
1860 families[famName]=0;
1861 famsFetched.insert(famName);
1866 std::vector<std::string> allFams=getFamiliesNames();
1867 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1868 std::set<std::string> unFetchedIds;
1869 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1870 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1871 families[*it4]=_families[*it4];
1876 * This method normalizes fam id with the following policy.
1877 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1878 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1879 * This method will throw an exception if a same family id is detected in different level.
1881 void MEDFileMesh::normalizeFamIdsMEDFile()
1883 ensureDifferentFamIdsPerLevel();
1884 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1885 std::vector<int> levs=getNonEmptyLevelsExt();
1886 std::set<int> levsS(levs.begin(),levs.end());
1887 std::set<std::string> famsFetched;
1888 std::map<std::string,mcIdType> families;
1890 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1893 const DataArrayIdType *fam=getFamilyFieldAtLevel(1);
1896 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1897 std::map<mcIdType,mcIdType> ren;
1898 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
1900 mcIdType nbOfTuples=fam->getNumberOfTuples();
1901 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1902 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1904 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1906 if(allIds->presenceOfValue(*it))
1908 std::string famName=getFamilyNameGivenId(*it);
1909 families[famName]=ren[*it];
1910 famsFetched.insert(famName);
1916 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1918 const DataArrayIdType *fam=getFamilyFieldAtLevel(*it2);
1921 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1922 std::map<mcIdType,mcIdType> ren;
1923 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
1925 mcIdType nbOfTuples=fam->getNumberOfTuples();
1926 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1927 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1929 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1931 if(allIds->presenceOfValue(*it))
1933 std::string famName=getFamilyNameGivenId(*it);
1934 families[famName]=ren[*it];
1935 famsFetched.insert(famName);
1941 std::vector<std::string> allFams=getFamiliesNames();
1942 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1943 std::set<std::string> unFetchedIds;
1944 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1945 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1946 families[*it4]=_families[*it4];
1951 * Returns a name of the family by its id. If there are several families having the given
1952 * id, the name first in lexical order is returned.
1953 * \param [in] id - the id of the family whose name is required.
1954 * \return std::string - the name of the found family.
1955 * \throw If no family with the given \a id exists.
1957 std::string MEDFileMesh::getFamilyNameGivenId(mcIdType id) const
1959 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1960 if((*it).second==id)
1962 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1963 throw INTERP_KERNEL::Exception(oss.str().c_str());
1967 * Returns a string describing \a this mesh. This description includes the mesh name and
1968 * the mesh description string.
1969 * \return std::string - the mesh information string.
1971 std::string MEDFileMesh::simpleRepr() const
1973 std::ostringstream oss;
1974 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1975 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1976 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1981 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1982 * an empty one is created.
1984 DataArrayIdType *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1986 DataArrayIdType *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1989 MCAuto<DataArrayIdType> arr(DataArrayIdType::New());
1990 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1991 arr->fillWithZero();
1992 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1993 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1997 * Returns ids of mesh entities contained in a given group of a given dimension.
1998 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2000 * \param [in] grp - the name of the group of interest.
2001 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2002 * returned instead of ids.
2003 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2004 * numbers, if available and required, of mesh entities of the group. The caller
2005 * is to delete this array using decrRef() as it is no more needed.
2006 * \throw If the name of a nonexistent group is specified.
2007 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2009 DataArrayIdType *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2011 std::vector<std::string> tmp(1);
2013 DataArrayIdType *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
2019 * Returns ids of mesh entities contained in given groups of a given dimension.
2020 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2022 * \param [in] grps - the names of the groups of interest.
2023 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2024 * returned instead of ids.
2025 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2026 * numbers, if available and required, of mesh entities of the groups. The caller
2027 * is to delete this array using decrRef() as it is no more needed.
2028 * \throw If the name of a nonexistent group is present in \a grps.
2029 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2031 DataArrayIdType *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2033 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2034 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
2038 * Returns ids of mesh entities contained in a given family of a given dimension.
2039 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2041 * \param [in] fam - the name of the family of interest.
2042 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2043 * returned instead of ids.
2044 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2045 * numbers, if available and required, of mesh entities of the family. The caller
2046 * is to delete this array using decrRef() as it is no more needed.
2047 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2049 DataArrayIdType *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2051 std::vector<std::string> tmp(1);
2053 DataArrayIdType *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
2059 * Returns ids of nodes contained in a given group.
2060 * \param [in] grp - the name of the group of interest.
2061 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2062 * returned instead of ids.
2063 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2064 * numbers, if available and required, of nodes of the group. The caller
2065 * is to delete this array using decrRef() as it is no more needed.
2066 * \throw If the name of a nonexistent group is specified.
2067 * \throw If the family field is missing for nodes.
2069 DataArrayIdType *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
2071 std::vector<std::string> tmp(1);
2073 DataArrayIdType *ret=getNodeGroupsArr(tmp,renum);
2079 * Returns ids of nodes contained in given groups.
2080 * \param [in] grps - the names of the groups of interest.
2081 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2082 * returned instead of ids.
2083 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2084 * numbers, if available and required, of nodes of the groups. The caller
2085 * is to delete this array using decrRef() as it is no more needed.
2086 * \throw If the name of a nonexistent group is present in \a grps.
2087 * \throw If the family field is missing for nodes.
2089 DataArrayIdType *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
2091 return getGroupsArr(1,grps,renum);
2095 * Returns ids of nodes contained in a given family.
2096 * \param [in] fam - the name of the family of interest.
2097 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2098 * returned instead of ids.
2099 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2100 * numbers, if available and required, of nodes of the family. The caller
2101 * is to delete this array using decrRef() as it is no more needed.
2102 * \throw If the name of a nonexistent family is specified.
2103 * \throw If the family field is missing for nodes.
2105 DataArrayIdType *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
2107 std::vector<std::string> tmp(1);
2109 DataArrayIdType *ret=getNodeFamiliesArr(tmp,renum);
2115 * Returns ids of nodes contained in given families.
2116 * \param [in] fams - the names of the families of interest.
2117 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2118 * returned instead of ids.
2119 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2120 * numbers, if available and required, of nodes of the families. The caller
2121 * is to delete this array using decrRef() as it is no more needed.
2122 * \throw If the family field is missing for nodes.
2124 DataArrayIdType *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2126 return getFamiliesArr(1,fams,renum);
2130 * Adds groups of given dimension and creates corresponding families and family fields
2131 * given ids of mesh entities of each group.
2132 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2133 * \param [in] grps - a sequence of arrays of ids each describing a group.
2134 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2136 * \throw If names of some groups in \a grps are equal.
2137 * \throw If \a grps includes a group with an empty name.
2138 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2139 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2141 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayIdType *>& grps, bool renum)
2145 std::set<std::string> grpsName;
2146 std::vector<std::string> grpsName2(grps.size());
2149 for(std::vector<const DataArrayIdType *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2151 grpsName.insert((*it)->getName());
2152 grpsName2[i]=(*it)->getName();
2154 if(grpsName.size()!=grps.size())
2155 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2156 if(grpsName.find(std::string(""))!=grpsName.end())
2157 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2158 mcIdType sz=getSizeAtLevel(meshDimRelToMaxExt);
2159 MCAuto<DataArrayIdType> fam;
2160 std::vector< std::vector<mcIdType> > fidsOfGroups;
2163 fam=DataArrayIdType::MakePartition(grps,sz,fidsOfGroups);
2167 std::vector< MCAuto<DataArrayIdType> > grps2(grps.size());
2168 for(unsigned int ii=0;ii<grps.size();ii++)
2170 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2171 grps2[ii]->setName(grps[ii]->getName());
2173 std::vector<const DataArrayIdType *> grps3(grps2.begin(),grps2.end());
2174 fam=DataArrayIdType::MakePartition(grps3,sz,fidsOfGroups);
2177 if(!_families.empty())
2178 offset=getMaxAbsFamilyId()+1;
2179 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2180 MCAuto<DataArrayIdType> ids=fam->getDifferentValues();
2181 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2182 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2186 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2187 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2188 * For the moment, the two last input parameters are not taken into account.
2190 void MEDFileMesh::appendFamilyEntries(const DataArrayIdType *famIds, const std::vector< std::vector<mcIdType> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2192 std::map<mcIdType,std::string> famInv;
2193 for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
2195 std::ostringstream oss;
2196 oss << "Family_" << (*it);
2197 _families[oss.str()]=(*it);
2198 famInv[*it]=oss.str();
2201 for(std::vector< std::vector<mcIdType> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2203 for(std::vector<mcIdType>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2205 _groups[grpNames[i]].push_back(famInv[*it2]);
2210 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2212 std::vector<int> levs(getNonEmptyLevels());
2213 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2214 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2216 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2217 ret.insert(ret.end(),elts.begin(),elts.end());
2223 * \sa getAllDistributionOfTypes
2225 std::vector<mcIdType> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2227 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2228 return mLev->getDistributionOfTypes();
2231 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2233 loadLL(fid,mName,dt,it,mrs);
2234 loadJointsFromFile(fid);
2235 loadEquivalences(fid);
2238 void MEDFileMesh::TranslateFamilyIds(mcIdType offset, DataArrayIdType *famArr, std::vector< std::vector<mcIdType> >& famIdsPerGrp)
2240 famArr->applyLin(offset>0?1:-1,offset,0);
2241 for(std::vector< std::vector<mcIdType> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2244 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<mcIdType>());
2245 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind(std::plus<mcIdType>(),std::placeholders::_1,offset));
2250 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2251 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2252 * If this method fails to find such a name it will throw an exception.
2254 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2257 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2260 std::size_t len=nameTry.length();
2261 for(std::size_t ii=1;ii<len;ii++)
2263 std::string tmp=nameTry.substr(ii,len-ii);
2264 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2270 for(char i=1;i<30;i++)
2272 std::string tmp1(nameTry.at(0),i);
2274 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2280 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2282 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2284 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2287 mcIdType MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<mcIdType>& code, mcIdType strt)
2289 std::size_t nbOfChunks=code.size()/3;
2290 if(code.size()%3!=0)
2291 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2293 for(std::size_t i=0;i<nbOfChunks;i++)
2302 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2303 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2304 * If _name is not empty and that 'm' has the same name nothing is done.
2305 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2307 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2310 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2315 std::string name(m->getName());
2320 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2321 oss << name << "' ! Names must match !";
2322 throw INTERP_KERNEL::Exception(oss.str().c_str());
2326 if(_desc_name.empty())
2327 _desc_name=m->getDescription();
2330 std::string name(m->getDescription());
2333 if(_desc_name!=name)
2335 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2336 oss << name << "' ! Names must match !";
2337 throw INTERP_KERNEL::Exception(oss.str().c_str());
2343 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2345 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2346 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
2348 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2349 oss << " - Groups lying on this family : ";
2350 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2351 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2352 oss << std::endl << std::endl;
2357 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2358 * file. The mesh to load is specified by its name and numbers of a time step and an
2360 * \param [in] fileName - the name of MED file to read.
2361 * \param [in] mName - the name of the mesh to read.
2362 * \param [in] dt - the number of a time step.
2363 * \param [in] it - the number of an iteration.
2364 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2365 * mesh using decrRef() as it is no more needed.
2366 * \throw If the file is not readable.
2367 * \throw If there is no mesh with given attributes in the file.
2368 * \throw If the mesh in the file is not an unstructured one.
2370 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2372 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2373 return New(fid,mName,dt,it,mrs);
2376 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2378 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2382 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2383 * file. The first mesh in the file is loaded.
2384 * \param [in] fileName - the name of MED file to read.
2385 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2386 * mesh using decrRef() as it is no more needed.
2387 * \throw If the file is not readable.
2388 * \throw If there is no meshes in the file.
2389 * \throw If the mesh in the file is not an unstructured one.
2391 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2393 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2394 return New(fid,mrs);
2398 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2400 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2403 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2404 throw INTERP_KERNEL::Exception(oss.str().c_str());
2407 MEDCoupling::MEDCouplingMeshType meshType;
2409 MEDCoupling::MEDCouplingAxisType dummy3;
2410 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2411 return T::New(fid,ms.front(),dt,it,mrs);
2414 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2416 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2420 * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2421 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2423 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2426 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2427 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2428 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2429 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2431 m2D->setCoords(m3D->getCoords());
2432 ret->setMeshAtLevel(0,m3D);
2433 ret->setMeshAtLevel(-1,m2D);
2434 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<med_int>::max()-mem->get2DCellIdForExtrusion());
2439 * Returns an empty instance of MEDFileUMesh.
2440 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2441 * mesh using decrRef() as it is no more needed.
2443 MEDFileUMesh *MEDFileUMesh::New()
2445 return new MEDFileUMesh;
2449 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2450 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2451 * \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.
2452 * 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
2453 * at most the memory consumtion.
2455 * \param [in] fileName - the name of the file.
2456 * \param [in] mName - the name of the mesh to be read.
2457 * \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.
2458 * \param [in] slicPerTyp - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
2459 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2460 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2461 * \param [in] mrs - the request for what to be loaded.
2462 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2464 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)
2466 MEDFileUtilities::CheckFileForRead(fileName);
2467 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2468 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2472 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2473 * This method is \b NOT wrapped into python.
2475 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)
2477 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2478 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2483 * This method is an helper to load only consecutive nodes chunk of data of MED file pointed by \a fileName.
2484 * Consecutive chunk is specified classicaly by start (included) stop (excluded) format with \a startNodeId and \a stopNodeId respectively.
2485 * This method returns 5 elements.
2487 * \param [in] fileName - Name of file nodes to be read of.
2488 * \param [in] mName - Name of the mesh inside file pointed be \a fileName nodes to be read of.
2489 * \param [in] dt - Time iteration inside file pointed be \a fileName nodes to be read of.
2490 * \param [in] it - Time order inside file pointed be \a fileName nodes to be read of.
2491 * \param [in] infosOnComp - Components info of nodes to be read of. The size of string vector should be equal to space dimension of mesh to be read.
2492 * \param [in] startNodeId - Start Node Id (included) of chunk of data to be read
2493 * \param [in] stopNodeId - Start Node Id (included) of chunk of data to be read
2494 * \param [out] coords - output coordinates of requested chunk (DataArrayDouble)
2495 * \param [out] partCoords - output PartDefinition object of chunk
2496 * \param [out] famCoords - output family id field of requested chunk (DataArrayIdType)
2497 * \param [out] numCoords - output num id field of requested chunk (DataArrayIdType)
2498 * \param [out] nameCoords - output names on nodes of requested chunk (DataArrayAsciiChar)
2500 * \sa MEDLoaderUMesh::LoadPartOf
2502 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,
2503 MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<DataArrayIdType>& famCoords, MCAuto<DataArrayIdType>& numCoords, MCAuto<DataArrayAsciiChar>& nameCoords)
2505 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2506 MEDFileUMeshL2::LoadPartCoords(fid,infosOnComp,mName,dt,it,startNodeId,stopNodeId,coords,partCoords,famCoords,numCoords,nameCoords);
2509 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2511 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2512 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2516 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2518 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2519 ret.push_back((const DataArrayDouble*)_coords);
2520 ret.push_back((const DataArrayIdType *)_fam_coords);
2521 ret.push_back((const DataArrayIdType *)_num_coords);
2522 ret.push_back((const DataArrayIdType *)_global_num_coords);
2523 ret.push_back((const DataArrayIdType *)_rev_num_coords);
2524 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2525 ret.push_back((const PartDefinition *)_part_coords);
2526 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2527 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2528 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2529 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2533 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2535 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2539 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2541 return new MEDFileUMesh;
2544 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2546 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2547 ret->deepCpyEquivalences(*this);
2548 if(_coords.isNotNull())
2549 ret->_coords=_coords->deepCopy();
2550 if(_fam_coords.isNotNull())
2551 ret->_fam_coords=_fam_coords->deepCopy();
2552 if(_num_coords.isNotNull())
2553 ret->_num_coords=_num_coords->deepCopy();
2554 if(_global_num_coords.isNotNull())
2555 ret->_global_num_coords=_global_num_coords->deepCopy();
2556 if(_rev_num_coords.isNotNull())
2557 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2558 if(_name_coords.isNotNull())
2559 ret->_name_coords=_name_coords->deepCopy();
2561 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2563 if((const MEDFileUMeshSplitL1 *)(*it))
2564 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2566 if((const PartDefinition*)_part_coords)
2567 ret->_part_coords=_part_coords->deepCopy();
2572 * Checks if \a this and another mesh are equal.
2573 * \param [in] other - the mesh to compare with.
2574 * \param [in] eps - a precision used to compare real values.
2575 * \param [in,out] what - the string returning description of unequal data.
2576 * \return bool - \c true if the meshes are equal, \c false, else.
2578 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2580 if(!MEDFileMesh::isEqual(other,eps,what))
2582 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2585 what="Mesh types differ ! This is unstructured and other is NOT !";
2588 clearNonDiscrAttributes();
2589 otherC->clearNonDiscrAttributes();
2590 const DataArrayDouble *coo1=_coords;
2591 const DataArrayDouble *coo2=otherC->_coords;
2592 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2594 what="Mismatch of coordinates ! One is defined and not other !";
2599 bool ret=coo1->isEqual(*coo2,eps);
2602 what="Coords differ !";
2607 const DataArrayIdType *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2608 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2610 what="Mismatch of families arr on nodes ! One is defined and not other !";
2615 bool ret=famc1->isEqual(*famc2);
2618 what="Families arr on node differ !";
2624 const DataArrayIdType *numc1(_num_coords),*numc2(otherC->_num_coords);
2625 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2627 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2632 bool ret=numc1->isEqual(*numc2);
2635 what="Numbering arr on node differ !";
2641 const DataArrayIdType *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2642 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2644 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2649 bool ret=gnumc1->isEqual(*gnumc2);
2652 what="Global numbering arr on node differ !";
2658 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2659 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2661 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2666 bool ret=namec1->isEqual(*namec2);
2669 what="Names arr on node differ !";
2674 if(_ms.size()!=otherC->_ms.size())
2676 what="Number of levels differs !";
2679 std::size_t sz=_ms.size();
2680 for(std::size_t i=0;i<sz;i++)
2682 const MEDFileUMeshSplitL1 *s1=_ms[i];
2683 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2684 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2686 what="Mismatch of presence of sub levels !";
2691 bool ret=s1->isEqual(s2,eps,what);
2696 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2699 if((!pd0 && pd1) || (pd0 && !pd1))
2701 what=std::string("node part def is defined only for one among this or other !");
2704 return pd0->isEqual(pd1,what);
2708 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2709 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2710 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2711 * \throw if internal family array is inconsistent
2712 * \sa checkSMESHConsistency()
2714 void MEDFileUMesh::checkConsistency() const
2716 if(!_coords || !_coords->isAllocated())
2719 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2721 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2722 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2723 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2727 mcIdType nbCoo = _coords->getNumberOfTuples();
2728 if (_fam_coords.isNotNull())
2729 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2730 if (_num_coords.isNotNull())
2732 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2734 mcIdType maxValue=_num_coords->getMaxValue(pos);
2735 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2736 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2738 if (_global_num_coords.isNotNull())
2740 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2742 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2743 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2744 if (_num_coords && !_num_coords->hasUniqueValues())
2745 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2747 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2748 // Now sub part check:
2749 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2750 it != _ms.end(); it++)
2751 (*it)->checkConsistency();
2756 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2757 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2758 * entities as it likes), or non overlapping between all sub-levels.
2759 * \throw if the condition above is not respected
2761 void MEDFileUMesh::checkSMESHConsistency() const
2764 // For all sub-levels, numbering is either always null or with void intersection:
2767 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2768 std::vector< const DataArrayIdType * > v;
2769 bool voidOrNot = ((*it)->_num == 0);
2770 for (it++; it != _ms.end(); it++)
2771 if( ((*it)->_num == 0) != voidOrNot )
2772 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2773 else if (!voidOrNot)
2774 v.push_back((*it)->_num);
2777 // don't forget the 1st one:
2778 v.push_back(_ms[0]->_num);
2779 MCAuto<DataArrayIdType> inter = DataArrayIdType::BuildIntersection(v);
2780 if (inter->getNumberOfTuples())
2781 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2787 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2788 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2790 void MEDFileUMesh::clearNodeAndCellNumbers()
2792 _num_coords.nullify();
2793 _rev_num_coords.nullify();
2794 _global_num_coords.nullify();
2795 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2797 (*it)->_num.nullify();
2798 (*it)->_rev_num.nullify();
2799 (*it)->_global_num.nullify();
2804 * Clears redundant attributes of incorporated data arrays.
2806 void MEDFileUMesh::clearNonDiscrAttributes() const
2808 MEDFileMesh::clearNonDiscrAttributes();
2809 if(_coords.isNotNull())
2810 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2811 if(_fam_coords.isNotNull())
2812 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2813 if(_num_coords.isNotNull())
2814 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2815 if(_name_coords.isNotNull())
2816 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2817 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2819 if((*it).isNotNull())
2820 (*it)->clearNonDiscrAttributes();
2824 void MEDFileUMesh::setName(const std::string& name)
2826 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2827 if((*it).isNotNull())
2828 (*it)->setName(name);
2829 MEDFileMesh::setName(name);
2832 MEDFileUMesh::MEDFileUMesh()
2836 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2839 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2841 catch(INTERP_KERNEL::Exception& e)
2847 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2848 * See MEDFileUMesh::LoadPartOf for detailed description.
2852 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)
2854 MEDFileUMeshL2 loaderl2;
2855 MEDCoupling::MEDCouplingMeshType meshType;
2858 MEDCoupling::MEDCouplingAxisType dummy3;
2859 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2860 if(meshType!=UNSTRUCTURED)
2862 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2863 throw INTERP_KERNEL::Exception(oss.str().c_str());
2865 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2866 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2870 * \brief Write joints in a file
2872 void MEDFileMesh::writeJoints(med_idt fid) const
2874 if ( _joints.isNotNull() )
2875 _joints->writeLL(fid);
2879 * \brief Load joints in a file or use provided ones
2881 //================================================================================
2883 * \brief Load joints in a file or use provided ones
2884 * \param [in] fid - MED file descriptor
2885 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2886 * Usually this joints are those just read by another iteration
2887 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2889 //================================================================================
2891 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2893 if ( toUseInstedOfReading )
2894 setJoints( toUseInstedOfReading );
2896 _joints = MEDFileJoints::New( fid, _name );
2899 void MEDFileMesh::loadEquivalences(med_idt fid)
2901 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2903 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2906 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2908 const MEDFileEquivalences *equiv(other._equiv);
2910 _equiv=equiv->deepCopy(this);
2913 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2915 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2916 if(!thisEq && !otherEq)
2918 if(thisEq && otherEq)
2919 return thisEq->isEqual(otherEq,what);
2922 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2927 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2929 const MEDFileEquivalences *equiv(_equiv);
2932 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2933 _equiv->getRepr(oss);
2936 void MEDFileMesh::checkCartesian() const
2938 if(getAxisType()!=AX_CART)
2940 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()) << ").";
2941 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2942 oss << " - call setAxisType(AX_CART)" << std::endl;
2943 oss << " - call cartesianize()";
2944 throw INTERP_KERNEL::Exception(oss.str().c_str());
2949 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2951 int MEDFileMesh::getNumberOfJoints() const
2953 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2957 * \brief Return joints with all adjacent mesh domains
2959 MEDFileJoints * MEDFileMesh::getJoints() const
2961 return const_cast<MEDFileJoints*>(& (*_joints));
2964 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2966 if ( joints != _joints )
2975 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2977 * \sa loadPartUMeshFromFile
2979 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2981 MEDFileUMeshL2 loaderl2;
2982 MEDCoupling::MEDCouplingMeshType meshType;
2985 MEDCoupling::MEDCouplingAxisType axType;
2986 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2987 setAxisType(axType);
2988 if(meshType!=UNSTRUCTURED)
2990 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2991 throw INTERP_KERNEL::Exception(oss.str().c_str());
2993 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2994 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2995 // Structure element part...
2996 med_int nModels(-1);
2998 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2999 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
3003 _elt_str.resize(nModels);
3004 for(int i=0;i<nModels;i++)
3005 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
3008 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
3010 int lev=loaderl2.getNumberOfLevels();
3012 for(int i=0;i<lev;i++)
3014 if(!loaderl2.emptyLev(i))
3015 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
3019 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
3021 setName(loaderl2.getName());
3022 setDescription(loaderl2.getDescription());
3023 setUnivName(loaderl2.getUnivName());
3024 setIteration(loaderl2.getIteration());
3025 setOrder(loaderl2.getOrder());
3026 setTimeValue(loaderl2.getTime());
3027 setTimeUnit(loaderl2.getTimeUnit());
3028 _coords=loaderl2.getCoords();
3029 if(!mrs || mrs->isNodeFamilyFieldReading())
3030 _fam_coords=loaderl2.getCoordsFamily();
3031 if(!mrs || mrs->isNodeNumFieldReading())
3032 _num_coords=loaderl2.getCoordsNum();
3033 if(!mrs || mrs->isNodeNameFieldReading())
3034 _name_coords=loaderl2.getCoordsName();
3035 if(!mrs || mrs->isGlobalNodeNumFieldReading())
3036 _global_num_coords=loaderl2.getCoordsGlobalNum();
3037 _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] meshDimRelToMaxExt - 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 * - 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;
4115 // !!! The core of the duplication logic is in these 2 methods:
4117 DAInt nodeIdsToDuplicate = m0->findNodesToDuplicate(*m11); // identify nodes to duplicate
4118 m0->findCellsToRenumber(*m11, nodeIdsToDuplicate->begin(), nodeIdsToDuplicate->end(), tmp11,tmp22); // identify cells needing renumbering
4119 DAInt cellsToModifyConn0(tmp11);
4120 DAInt cellsToModifyConn1(tmp22);
4123 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4124 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4125 DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New();
4126 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4127 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4128 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4129 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4130 DataArrayIdType *cellsInM1ToRenumW4Tmp=0;
4131 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4132 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4133 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4134 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4135 DAInt grpIds=getGroupArr(-1,grpNameM1);
4136 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4137 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4138 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4139 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4140 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4141 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4142 m0->setCoords(tmp0->getCoords());
4143 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4144 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4145 m1->setCoords(m0->getCoords());
4146 _coords=m0->getCoords(); _coords->incrRef();
4147 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4148 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4149 DataArrayIdType * duplCells;
4150 m1->areCellsIncludedIn(m11, 0, duplCells);
4151 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4152 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4153 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4154 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4155 DAInt szOfCellGrpOfSameType(tmp00);
4156 DAInt idInMsOfCellGrpOfSameType(tmp11);
4158 newm1->setName(getName());
4159 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
4161 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4162 DAInt newFam=DataArrayIdType::New();
4163 newFam->alloc(newm1->getNumberOfCells(),1);
4164 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4165 // Positive ID for family of nodes, negative for all the rest.
4167 if (m1->getMeshDimension() == 0)
4168 idd=getMaxFamilyId()+1;
4170 idd=getMinFamilyId()-1;
4171 mcIdType globStart=0,start=0,end,globEnd;
4172 mcIdType nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4173 for(mcIdType i=0;i<nbOfChunks;i++)
4175 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4176 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4178 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4179 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4180 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4185 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4189 newm1->setCoords(getCoords());
4190 setMeshAtLevel(-1,newm1);
4191 setFamilyFieldArr(-1,newFam);
4192 std::string grpName2(grpNameM1); grpName2+="_dup";
4193 addFamily(grpName2,idd);
4194 addFamilyOnGrp(grpName2,grpName2);
4199 mcIdType newNbOfNodes=getCoords()->getNumberOfTuples();
4200 newFam=DataArrayIdType::New(); newFam->alloc(newNbOfNodes,1);
4201 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4202 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4206 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4208 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4209 it != _ms.end(); it++)
4212 (*it)->_rev_num = 0;
4214 nodesDuplicated=nodeIdsToDuplicate.retn();
4215 cellsModified=cellsToModifyConn0.retn();
4216 cellsNotModified=cellsToModifyConn1.retn();
4219 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4220 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4223 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4224 * \param [out] newCode retrieves the distribution of types after the call if true is returned
4225 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4227 * \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.
4228 * 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.
4230 bool MEDFileUMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
4232 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4233 std::vector<int> levs=getNonEmptyLevels();
4235 std::vector< const DataArrayIdType* > renumCellsSplited;//same than memorySaverIfThrow
4236 std::vector< MCAuto<DataArrayIdType> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4239 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4241 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4242 std::vector<mcIdType> code1=m->getDistributionOfTypes();
4243 end=PutInThirdComponentOfCodeOffset(code1,start);
4244 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4245 bool hasChanged=m->unPolyze();
4246 DataArrayIdType *fake=0;
4247 MCAuto<DataArrayIdType> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4248 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4250 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4253 MCAuto<DataArrayIdType> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4254 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4256 MCAuto<DataArrayIdType> famField2,numField2;
4257 const DataArrayIdType *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayIdType *>(famField); }
4258 const DataArrayIdType *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayIdType *>(numField); }
4259 setMeshAtLevel(*it,m);
4260 std::vector<mcIdType> code2=m->getDistributionOfTypes();
4261 end=PutInThirdComponentOfCodeOffset(code2,start);
4262 newCode.insert(newCode.end(),code2.begin(),code2.end());
4264 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4268 MCAuto<DataArrayIdType> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4269 setFamilyFieldArr(*it,newFamField);
4273 MCAuto<DataArrayIdType> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4274 setRenumFieldArr(*it,newNumField);
4279 newCode.insert(newCode.end(),code1.begin(),code1.end());
4285 MCAuto<DataArrayIdType> renumCells=DataArrayIdType::Aggregate(renumCellsSplited);
4286 MCAuto<DataArrayIdType> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4287 o2nRenumCell=o2nRenumCellRet.retn();
4292 /*! \cond HIDDEN_ITEMS */
4293 struct MEDLoaderAccVisit1
4295 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4296 mcIdType operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4297 mcIdType _new_nb_of_nodes;
4302 * 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.
4303 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4304 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4305 * -1 values in returned array means that the corresponding old node is no more used.
4307 * \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
4308 * is modified in \a this.
4309 * \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
4312 DataArrayIdType *MEDFileUMesh::zipCoords()
4314 const DataArrayDouble *coo(getCoords());
4316 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4317 mcIdType nbOfNodes(coo->getNumberOfTuples());
4318 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4319 std::vector<int> neLevs(getNonEmptyLevels());
4320 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4322 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4323 if(zeLev->isMeshStoredSplitByType())
4325 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4326 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4328 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4332 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4333 mesh->computeNodeIdsAlg(nodeIdsInUse);
4336 mcIdType nbrOfNodesInUse((mcIdType)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4337 if(nbrOfNodesInUse==nbOfNodes)
4338 return 0;//no need to update _part_coords
4339 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfNodes,1);
4340 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4341 MCAuto<DataArrayIdType> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4342 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4343 MCAuto<DataArrayIdType> newFamCoords;
4344 MCAuto<DataArrayAsciiChar> newNameCoords;
4345 if((const DataArrayIdType *)_fam_coords)
4346 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4347 MCAuto<DataArrayIdType> newNumCoords,newGlobalNumCoords;
4348 if(_num_coords.isNotNull())
4349 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4350 if(_global_num_coords.isNotNull())
4351 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4352 if(_name_coords.isNotNull())
4353 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4354 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4355 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4357 if((MEDFileUMeshSplitL1*)*it)
4359 (*it)->renumberNodesInConn(ret->begin());
4360 (*it)->setCoords(_coords);
4363 // updates _part_coords
4364 const PartDefinition *pc(_part_coords);
4367 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4368 _part_coords=tmpPD->composeWith(pc);
4374 * This method is the extension of MEDCouplingUMesh::computeFetchedNodeIds. Except that here all levels are considered here.
4376 * \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.
4378 DataArrayIdType *MEDFileUMesh::computeFetchedNodeIds() const
4380 std::vector<int> neLevs(this->getNonEmptyLevels());
4381 std::vector<bool> nodesHighlighted(this->getNumberOfNodes(),false);
4382 for(auto lev : neLevs)
4384 const MEDFileUMeshSplitL1 *zeLev(this->getMeshAtLevSafe(lev));
4385 zeLev->highlightUsedNodes(nodesHighlighted);
4387 return DataArrayIdType::BuildListOfSwitchedOn(nodesHighlighted);
4391 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4392 * The extraction of \a this is specified by the extractDef \a input map.
4393 * This map tells for each level of cells, the cells kept in the extraction.
4395 * \return - a new reference of DataArrayIdType that represents sorted node ids, the extraction is lying on.
4396 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4398 DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4400 std::vector<int> levs(getNonEmptyLevels());
4401 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4402 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4405 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4406 if((*it).second.isNull())
4407 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4410 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4412 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4413 throw INTERP_KERNEL::Exception(oss.str());
4415 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4416 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4417 mPart->computeNodeIdsAlg(fetchedNodes);
4419 return DataArrayIdType::BuildListOfSwitchedOn(fetchedNodes);
4423 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4425 * \return - a new reference of MEDFileUMesh
4426 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4428 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4430 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4431 std::vector<int> levs(getNonEmptyLevels());
4432 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4435 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4436 if((*it).second.isNull())
4437 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4440 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4442 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4443 throw INTERP_KERNEL::Exception(oss.str());
4445 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4446 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4447 ret->setMeshAtLevel((*it).first,mPart);
4448 const DataArrayIdType *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4451 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4452 ret->setFamilyFieldArr((*it).first,famPart);
4456 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4457 ret->setFamilyFieldArr((*it).first,numPart);
4460 std::map<int, MCAuto<DataArrayIdType> >::const_iterator it2(extractDef.find(1));
4461 if(it2!=extractDef.end())
4463 const DataArrayDouble *coo(ret->getCoords());
4465 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4466 MCAuto<DataArrayIdType> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4467 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4468 ret->setCoords(cooPart);
4469 const DataArrayIdType *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4472 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4473 ret->setFamilyFieldArr(1,famPart);
4477 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4478 ret->setFamilyFieldArr(1,numPart);
4480 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4484 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4485 m->renumberNodesInConn(o2nNodes->begin());
4486 ret->setMeshAtLevel((*it3).first,m);
4493 * This method performs an extrusion along a path defined by \a m1D.
4494 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4495 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4496 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4497 * This method scans all levels in \a this
4498 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4500 * \param [in] m1D - the mesh defining the extrusion path.
4501 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4502 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4504 * \sa MEDCouplingUMesh::buildExtrudedMesh
4506 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4509 if(getMeshDimension()!=2)
4510 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4511 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4512 m1D->checkConsistencyLight();
4513 if(m1D->getMeshDimension()!=1)
4514 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4515 mcIdType nbRep(m1D->getNumberOfCells());
4516 std::vector<int> levs(getNonEmptyLevels());
4517 std::vector<std::string> grps(getGroupsNames());
4518 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4519 DataArrayDouble *coords(0);
4520 std::size_t nbOfLevsOut(levs.size()+1);
4521 std::vector< MCAuto<DataArrayIdType> > o2ns(nbOfLevsOut);
4522 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4524 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4525 item=item->clone(false);
4526 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4527 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4528 tmp->changeSpaceDimension(3+(*lev),0.);
4529 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4530 zeList.push_back(elt);
4532 coords=elt->getCoords();
4535 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4536 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4538 (*it)->setName(getName());
4539 (*it)->setCoords(coords);
4541 for(std::size_t ii=0;ii!=zeList.size();ii++)
4544 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4547 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4548 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4549 MCAuto<DataArrayIdType> tmp(elt2->getNodalConnectivity()->deepCopy());
4550 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4551 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4552 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4553 std::vector<const MEDCouplingUMesh *> elts(3);
4554 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4555 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4556 elt->setName(getName());
4559 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4560 ret->setMeshAtLevel(lev,elt);
4562 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4563 endLev=endLev->clone(false); endLev->setCoords(coords);
4564 MCAuto<DataArrayIdType> tmp(endLev->getNodalConnectivity()->deepCopy());
4565 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4566 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4567 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4568 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4569 endLev->setName(getName());
4570 ret->setMeshAtLevel(levs.back()-1,endLev);
4572 for(std::size_t ii=0;ii!=zeList.size();ii++)
4575 std::vector< MCAuto<DataArrayIdType> > outGrps;
4576 std::vector< const DataArrayIdType * > outGrps2;
4579 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4581 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev+1,*grp));
4582 if(!grpArr->empty())
4584 MCAuto<DataArrayIdType> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4585 mcIdType offset0(zeList[ii]->getNumberOfCells());
4586 mcIdType offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4587 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4588 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4589 grpArr2->setName(oss.str());
4590 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4591 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4592 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4593 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4598 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4600 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev,*grp));
4601 if(!grpArr->empty())
4603 mcIdType nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4604 std::vector< MCAuto<DataArrayIdType> > grpArrs(nbRep);
4605 std::vector< const DataArrayIdType *> grpArrs2(nbRep);
4606 for(int iii=0;iii<nbRep;iii++)
4608 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4609 grpArrs2[iii]=grpArrs[iii];
4611 MCAuto<DataArrayIdType> grpArrExt(DataArrayIdType::Aggregate(grpArrs2));
4612 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4613 std::ostringstream grpName; grpName << *grp << "_extruded";
4614 grpArrExt->setName(grpName.str());
4615 outGrps.push_back(grpArrExt);
4616 outGrps2.push_back(grpArrExt);
4619 ret->setGroupsAtLevel(lev,outGrps2);
4621 std::vector< MCAuto<DataArrayIdType> > outGrps;
4622 std::vector< const DataArrayIdType * > outGrps2;
4623 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4625 MCAuto<DataArrayIdType> grpArr1(getGroupArr(levs.back(),*grp));
4626 if(grpArr1->empty())
4628 MCAuto<DataArrayIdType> grpArr2(grpArr1->deepCopy());
4629 std::ostringstream grpName; grpName << *grp << "_top";
4630 grpArr2->setName(grpName.str());
4631 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4632 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4633 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4635 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4640 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4641 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4642 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4644 * \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
4645 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4646 * \param [in] eps - detection threshold for coordinates.
4647 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4649 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4651 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4654 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4655 mcIdType initialNbNodes(getNumberOfNodes());
4656 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4657 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4659 MCAuto<DataArrayIdType> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4661 DataArrayDouble *zeCoords(m0->getCoords());
4662 ret->setMeshAtLevel(0,m0);
4663 std::vector<int> levs(getNonEmptyLevels());
4664 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4667 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4668 ret->setFamilyFieldArr(0,famFieldCpy);
4670 famField=getFamilyFieldAtLevel(1);
4673 MCAuto<DataArrayIdType> fam(DataArrayIdType::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4674 fam->fillWithZero();
4675 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4676 ret->setFamilyFieldArr(1,fam);
4678 ret->copyFamGrpMapsFrom(*this);
4679 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4680 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4684 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4685 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4686 if(m1->getMeshDimension()!=0)
4689 MCAuto<DataArrayIdType> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4690 }//kill unused notUsed var
4691 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4692 DataArrayIdType *b(0);
4693 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4694 MCAuto<DataArrayIdType> bSafe(b);
4697 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4698 throw INTERP_KERNEL::Exception(oss.str().c_str());
4700 b->applyLin(1,initialNbNodes);
4701 MCAuto<DataArrayIdType> l0(DataArrayIdType::New()); l0->alloc(initialNbNodes,1); l0->iota();
4702 std::vector<const DataArrayIdType *> v(2); v[0]=l0; v[1]=b;
4703 MCAuto<DataArrayIdType> renum(DataArrayIdType::Aggregate(v));
4704 m1->renumberNodesInConn(renum->begin());
4706 m1->setCoords(zeCoords);
4707 ret->setMeshAtLevel(*lev,m1);
4708 famField=getFamilyFieldAtLevel(*lev);
4711 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4712 ret->setFamilyFieldArr(*lev,famFieldCpy);
4719 * This method converts all quadratic cells in \a this into linear cells.
4720 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4721 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4723 * \param [in] eps - detection threshold for coordinates.
4724 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4726 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4728 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4731 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4732 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4733 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4734 m0->convertQuadraticCellsToLinear();
4736 DataArrayDouble *zeCoords(m0->getCoords());
4737 ret->setMeshAtLevel(0,m0);
4738 std::vector<int> levs(getNonEmptyLevels());
4739 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4742 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4743 ret->setFamilyFieldArr(0,famFieldCpy);
4745 famField=getFamilyFieldAtLevel(1);
4748 MCAuto<DataArrayIdType> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4749 ret->setFamilyFieldArr(1,fam);
4751 ret->copyFamGrpMapsFrom(*this);
4752 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4756 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4757 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4758 m1->convertQuadraticCellsToLinear();
4760 DataArrayIdType *b(0);
4761 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4762 MCAuto<DataArrayIdType> bSafe(b);
4765 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4766 throw INTERP_KERNEL::Exception(oss.str().c_str());
4768 m1->renumberNodesInConn(b->begin());
4769 m1->setCoords(zeCoords);
4770 ret->setMeshAtLevel(*lev,m1);
4771 famField=getFamilyFieldAtLevel(*lev);
4774 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4775 ret->setFamilyFieldArr(*lev,famFieldCpy);
4782 * Computes the symmetry of \a this.
4783 * \return a new object.
4785 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4787 MCAuto<MEDFileUMesh> ret(deepCopy());
4788 DataArrayDouble *myCoo(getCoords());
4791 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4792 ret->setCoordsForced(newCoo);
4798 * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
4799 * merged in such a way that the final mesh contain all of them.
4800 * \return a new object.
4802 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4805 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4806 std::size_t sz(meshes.size()),i(0);
4807 std::vector<const DataArrayDouble *> coos(sz);
4808 std::vector<const DataArrayIdType *> fam_coos(sz),num_coos(sz);
4809 for(auto it=meshes.begin();it!=meshes.end();it++,i++)
4812 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4813 coos[i]=(*it)->getCoords();
4814 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4815 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4817 const MEDFileUMesh *ref(meshes[0]);
4818 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4819 std::vector<int> levs(ref->getNonEmptyLevels());
4820 std::map<int, std::vector<const DataArrayIdType *> > m_fam,m_renum;
4821 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4822 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4823 std::map<std::string,mcIdType> famNumMap;
4824 std::map<mcIdType, std::string> famNumMap_rev;
4825 std::map<std::string, std::vector<std::string> > grpFamMap;
4826 std::set< MCAuto<DataArrayIdType> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
4828 // Identify min family number used:
4829 mcIdType min_fam_num(0);
4830 for(const auto& msh : meshes)
4832 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4833 for(const auto& it3 : locMap1)
4834 if(it3.second < min_fam_num)
4835 min_fam_num = it3.second;
4838 for(const auto& msh : meshes)
4840 if(msh->getSpaceDimension()!=spaceDim)
4841 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4842 if(msh->getMeshDimension()!=meshDim)
4843 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4844 if(msh->getNonEmptyLevels()!=levs)
4845 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4847 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4848 std::map<std::string, std::string> substitute;
4849 std::map<mcIdType, mcIdType> substituteN;
4850 bool fam_conflict(false);
4851 for(const auto& it3 : locMap1)
4853 const std::string& famName = it3.first;
4854 mcIdType famNum = it3.second;
4855 if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
4857 // Is it used by a group of the current mesh or a group from a previous mesh?
4858 // If not, this is OK (typically -1 familly).
4861 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4862 for(const auto& it4 : locMap2)
4864 const auto& famLst = it4.second;
4865 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4866 { used = true; break; }
4868 // Previous meshes ...
4870 for(const auto& it4 : grpFamMap)
4872 const auto& famLst = it4.second;
4873 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4874 { used = true; break; }
4878 { // Generate a new family name, and a new family number
4879 fam_conflict = true;
4880 std::ostringstream oss;
4881 oss << "Family_" << --min_fam_num; // New ID
4882 std::string new_name(oss.str());
4883 substitute[famName] = new_name;
4884 substituteN[famNum] = min_fam_num;
4885 famNumMap[new_name] = min_fam_num;
4886 famNumMap_rev[min_fam_num] = new_name;
4889 famNumMap[famName] = famNum;
4890 famNumMap_rev[famNum] = famName;
4893 for(const auto& level : levs)
4895 MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
4896 m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
4897 m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
4899 // Family field - substitute new family number if needed:
4902 DataArrayIdType* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
4903 mem_cleanup.insert(MCAuto<DataArrayIdType>(dai)); // Make sure array will decrRef() at end of method
4904 for (const auto& subN : substituteN)
4905 dai->changeValue(subN.first, subN.second);
4906 m_fam[level].push_back(dai);
4909 m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
4912 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4913 for(const auto& grpItem : locMap2)
4915 const std::string& grpName = grpItem.first;
4916 std::vector<std::string> famLst;
4917 // Substitute family name in group description if needed:
4920 famLst = grpItem.second;
4921 for (const auto& sub : substitute)
4922 std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
4925 famLst = grpItem.second;
4927 // Potentially merge groups (if same name):
4928 const auto& it = grpFamMap.find(grpName);
4929 if (it != grpFamMap.end())
4931 // Group already exists, merge should be done. Normally we whould never
4932 // have twice the same family name in famLstCur and famLst since we dealt with family number
4933 // conflict just above ...
4934 std::vector<std::string>& famLstCur = (*it).second;
4935 famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
4938 grpFamMap[grpName] = famLst;
4941 // Easy part : nodes
4942 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4943 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4944 ret->setCoords(coo);
4945 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayIdType *)0)==fam_coos.end())
4947 MCAuto<DataArrayIdType> fam_coo(DataArrayIdType::Aggregate(fam_coos));
4948 ret->setFamilyFieldArr(1,fam_coo);
4950 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayIdType *)0)==num_coos.end())
4952 MCAuto<DataArrayIdType> num_coo(DataArrayIdType::Aggregate(num_coos));
4953 ret->setRenumFieldArr(1,num_coo);
4956 for(const auto& level : levs)
4958 auto it2(m_mesh.find(level));
4959 if(it2==m_mesh.end())
4960 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4961 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4962 mesh->setCoords(coo); mesh->setName(ref->getName());
4963 MCAuto<DataArrayIdType> renum(mesh->sortCellsInMEDFileFrmt());
4964 ret->setMeshAtLevel(level,mesh);
4965 auto it3(m_fam.find(level)),it4(m_renum.find(level));
4966 if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
4967 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
4968 if(it4==m_renum.end())
4969 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
4970 // Set new family field if it was defined for all input meshes
4971 const std::vector<const DataArrayIdType *>& fams((*it3).second);
4972 if(std::find(fams.begin(),fams.end(),(const DataArrayIdType *)0)==fams.end())
4974 MCAuto<DataArrayIdType> famm(DataArrayIdType::Aggregate(fams));
4975 famm->renumberInPlace(renum->begin());
4976 ret->setFamilyFieldArr(level,famm);
4978 // Set optional number field if defined for all input meshes:
4979 const std::vector<const DataArrayIdType *>& renums((*it4).second);
4980 if(std::find(renums.begin(),renums.end(),(const DataArrayIdType *)0)==renums.end())
4982 MCAuto<DataArrayIdType> renumm(DataArrayIdType::Aggregate(renums));
4983 renumm->renumberInPlace(renum->begin());
4984 ret->setRenumFieldArr(level,renumm);
4988 ret->setFamilyInfo(famNumMap);
4989 ret->setGroupInfo(grpFamMap);
4990 ret->setName(ref->getName());
4994 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4996 if(getMeshDimension()!=3)
4997 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4998 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4999 if(m3D.isNull() || m2D.isNull())
5000 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
5001 mcIdType zeId(std::numeric_limits<med_int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
5002 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
5006 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5008 clearNonDiscrAttributes();
5009 forceComputationOfParts();
5010 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
5011 std::vector<mcIdType> layer0;
5012 layer0.push_back(getAxisType());//0 i
5013 layer0.push_back(_order); //1 i
5014 layer0.push_back(_iteration);//2 i
5015 layer0.push_back(getSpaceDimension());//3 i
5016 tinyDouble.push_back(_time);//0 d
5017 tinyStr.push_back(_name);//0 s
5018 tinyStr.push_back(_desc_name);//1 s
5019 for(int i=0;i<getSpaceDimension();i++)
5020 tinyStr.push_back(_coords->getInfoOnComponent(i));
5021 layer0.push_back(ToIdType(_families.size()));//4 i <- key info aa layer#0
5022 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
5024 tinyStr.push_back((*it).first);
5025 layer0.push_back((*it).second);
5027 layer0.push_back((mcIdType)_groups.size());//4+aa i <- key info bb layer#0
5028 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
5030 layer0.push_back(ToIdType((*it0).second.size()));
5031 tinyStr.push_back((*it0).first);
5032 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
5033 tinyStr.push_back(*it1);
5035 // sizeof(layer0)==4+aa+1+bb layer#0
5036 bigArrayD=_coords;// 0 bd
5037 bigArraysI.push_back(_fam_coords);// 0 bi
5038 bigArraysI.push_back(_num_coords);// 1 bi
5039 const PartDefinition *pd(_part_coords);
5041 layer0.push_back(-1);
5044 std::vector<mcIdType> tmp0;
5045 pd->serialize(tmp0,bigArraysI);
5046 tinyInt.push_back(ToIdType(tmp0.size()));
5047 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
5050 std::vector<mcIdType> layer1;
5051 std::vector<int> levs(getNonEmptyLevels());
5052 layer1.push_back((mcIdType)levs.size());// 0 i <- key
5053 layer1.insert(layer1.end(),levs.begin(),levs.end());
5054 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
5056 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
5057 lev->serialize(layer1,bigArraysI);
5059 // put layers all together.
5060 tinyInt.push_back(ToIdType(layer0.size()));
5061 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
5062 tinyInt.push_back(ToIdType(layer1.size()));
5063 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
5066 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr,
5067 std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5069 mcIdType sz0(tinyInt[0]);
5070 std::vector<mcIdType> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
5071 mcIdType sz1(tinyInt[sz0+1]);
5072 std::vector<mcIdType> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
5074 std::reverse(layer0.begin(),layer0.end());
5075 std::reverse(layer1.begin(),layer1.end());
5076 std::reverse(tinyDouble.begin(),tinyDouble.end());
5077 std::reverse(tinyStr.begin(),tinyStr.end());
5078 std::reverse(bigArraysI.begin(),bigArraysI.end());
5080 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
5081 _order=FromIdType<int>(layer0.back()); layer0.pop_back();
5082 _iteration=FromIdType<int>(layer0.back()); layer0.pop_back();
5083 mcIdType spaceDim(layer0.back()); layer0.pop_back();
5084 _time=tinyDouble.back(); tinyDouble.pop_back();
5085 _name=tinyStr.back(); tinyStr.pop_back();
5086 _desc_name=tinyStr.back(); tinyStr.pop_back();
5087 _coords=bigArrayD; _coords->rearrange(spaceDim);
5088 for(int i=0;i<spaceDim;i++)
5090 _coords->setInfoOnComponent(i,tinyStr.back());
5093 mcIdType nbOfFams(layer0.back()); layer0.pop_back();
5095 for(mcIdType i=0;i<nbOfFams;i++)
5097 _families[tinyStr.back()]=layer0.back();
5098 tinyStr.pop_back(); layer0.pop_back();
5100 mcIdType nbGroups(layer0.back()); layer0.pop_back();
5102 for(mcIdType i=0;i<nbGroups;i++)
5104 std::string grpName(tinyStr.back()); tinyStr.pop_back();
5105 mcIdType nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
5106 std::vector<std::string> fams(nbOfFamsOnGrp);
5107 for(mcIdType j=0;j<nbOfFamsOnGrp;j++)
5109 fams[j]=tinyStr.back(); tinyStr.pop_back();
5111 _groups[grpName]=fams;
5113 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
5114 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
5116 mcIdType isPd(layer0.back()); layer0.pop_back();
5119 std::vector<mcIdType> tmp0(layer0.begin(),layer0.begin()+isPd);
5120 layer0.erase(layer0.begin(),layer0.begin()+isPd);
5121 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
5124 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
5126 mcIdType nbLevs(layer1.back()); layer1.pop_back();
5127 std::vector<mcIdType> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
5129 mcIdType maxLev(-(*std::min_element(levs.begin(),levs.end())));
5130 _ms.resize(maxLev+1);
5131 for(mcIdType i=0;i<nbLevs;i++)
5133 mcIdType lev(levs[i]);
5135 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
5140 * Adds a group of nodes to \a this mesh.
5141 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5142 * The ids should be sorted and different each other (MED file norm).
5144 * \warning this method can alter default "FAMILLE_ZERO" family.
5145 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5147 * \throw If the node coordinates array is not set.
5148 * \throw If \a ids == \c NULL.
5149 * \throw If \a ids->getName() == "".
5150 * \throw If \a ids does not respect the MED file norm.
5151 * \throw If a group with name \a ids->getName() already exists.
5153 void MEDFileUMesh::addNodeGroup(const DataArrayIdType *ids)
5155 const DataArrayDouble *coords(_coords);
5157 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
5158 mcIdType nbOfNodes(coords->getNumberOfTuples());
5159 if(_fam_coords.isNull())
5160 { _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
5162 addGroupUnderground(true,ids,_fam_coords);
5166 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5168 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5169 * The ids should be sorted and different each other (MED file norm).
5171 * \warning this method can alter default "FAMILLE_ZERO" family.
5172 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5174 * \throw If the node coordinates array is not set.
5175 * \throw If \a ids == \c NULL.
5176 * \throw If \a ids->getName() == "".
5177 * \throw If \a ids does not respect the MED file norm.
5178 * \throw If a group with name \a ids->getName() already exists.
5180 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
5182 std::vector<int> levs(getNonEmptyLevelsExt());
5183 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
5185 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
5186 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
5188 if(meshDimRelToMaxExt==1)
5189 { addNodeGroup(ids); return ; }
5190 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
5191 DataArrayIdType *fam(lev->getOrCreateAndGetFamilyField());
5192 addGroupUnderground(false,ids,fam);
5196 * Changes a name of a family specified by its id.
5197 * \param [in] id - the id of the family of interest.
5198 * \param [in] newFamName - the new family name.
5199 * \throw If no family with the given \a id exists.
5201 void MEDFileUMesh::setFamilyNameAttachedOnId(mcIdType id, const std::string& newFamName)
5203 std::string oldName=getFamilyNameGivenId(id);
5204 _families.erase(oldName);
5205 _families[newFamName]=id;
5209 * Removes a mesh of a given dimension.
5210 * \param [in] meshDimRelToMax - the relative dimension of interest.
5211 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
5213 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
5215 std::vector<int> levSet=getNonEmptyLevels();
5216 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
5217 if(it==levSet.end())
5218 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
5219 int pos=(-meshDimRelToMax);
5224 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
5225 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5226 * \param [in] m - the new mesh to set.
5227 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5229 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5230 * another node coordinates array.
5231 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5232 * to the existing meshes of other levels of \a this mesh.
5234 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5236 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5237 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5241 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5242 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5243 * \param [in] m - the new mesh to set.
5244 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5245 * writing \a this mesh in a MED file.
5246 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5248 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5249 * another node coordinates array.
5250 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5251 * to the existing meshes of other levels of \a this mesh.
5253 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5255 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5256 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5259 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5261 dealWithTinyInfo(m);
5262 std::vector<int> levSet=getNonEmptyLevels();
5263 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5265 if((DataArrayDouble *)_coords==0)
5267 DataArrayDouble *c=m->getCoords();
5272 if(m->getCoords()!=_coords)
5273 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5274 int sz=(-meshDimRelToMax)+1;
5275 if(sz>=(int)_ms.size())
5277 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5281 return _ms[-meshDimRelToMax];
5285 * This method allows to set at once the content of different levels in \a this.
5286 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5288 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5289 * \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.
5290 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5292 * \throw If \a there is a null pointer in \a ms.
5293 * \sa MEDFileUMesh::setMeshAtLevel
5295 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5299 const MEDCouplingUMesh *mRef=ms[0];
5301 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5302 std::string name(mRef->getName());
5303 const DataArrayDouble *coo(mRef->getCoords());
5306 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5308 const MEDCouplingUMesh *cur(*it);
5310 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5311 if(coo!=cur->getCoords())
5312 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5313 int mdim=cur->getMeshDimension();
5314 zeDim=std::max(zeDim,mdim);
5315 if(s.find(mdim)!=s.end())
5316 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5318 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5320 int mdim=(*it)->getMeshDimension();
5321 setName((*it)->getName());
5322 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5328 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5329 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5330 * The given meshes must share the same node coordinates array.
5331 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5332 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5333 * create in \a this mesh.
5334 * \throw If \a ms is empty.
5335 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5336 * to the existing meshes of other levels of \a this mesh.
5337 * \throw If the meshes in \a ms do not share the same node coordinates array.
5338 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5339 * of the given meshes.
5340 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5341 * \throw If names of some meshes in \a ms are equal.
5342 * \throw If \a ms includes a mesh with an empty name.
5344 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5347 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5348 int sz=(-meshDimRelToMax)+1;
5349 if(sz>=(int)_ms.size())
5351 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5352 DataArrayDouble *coo=checkMultiMesh(ms);
5353 if((DataArrayDouble *)_coords==0)
5359 if((DataArrayDouble *)_coords!=coo)
5360 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5361 std::vector<DataArrayIdType *> corr;
5362 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5363 std::vector< MCAuto<DataArrayIdType> > corr3(corr.begin(),corr.end());
5364 setMeshAtLevel(meshDimRelToMax,m,renum);
5365 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5366 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5370 * Creates groups at a given level in \a this mesh from a sequence of
5371 * meshes each representing a group.
5372 * The given meshes must share the same node coordinates array.
5373 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5374 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5375 * create in \a this mesh.
5376 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5378 * \throw If \a ms is empty.
5379 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5380 * to the existing meshes of other levels of \a this mesh.
5381 * \throw If the meshes in \a ms do not share the same node coordinates array.
5382 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5383 * of the given meshes.
5384 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5385 * \throw If names of some meshes in \a ms are equal.
5386 * \throw If \a ms includes a mesh with an empty name.
5388 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5391 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5392 int sz=(-meshDimRelToMax)+1;
5393 if(sz>=(int)_ms.size())
5395 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5396 DataArrayDouble *coo=checkMultiMesh(ms);
5397 if((DataArrayDouble *)_coords==0)
5403 if((DataArrayDouble *)_coords!=coo)
5404 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5405 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5406 std::vector< MCAuto<DataArrayIdType> > corr(ms.size());
5408 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5410 DataArrayIdType *arr=0;
5411 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5415 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5416 throw INTERP_KERNEL::Exception(oss.str().c_str());
5419 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5420 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5423 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5425 const DataArrayDouble *ret=ms[0]->getCoords();
5426 int mdim=ms[0]->getMeshDimension();
5427 for(unsigned int i=1;i<ms.size();i++)
5429 ms[i]->checkConsistencyLight();
5430 if(ms[i]->getCoords()!=ret)
5431 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5432 if(ms[i]->getMeshDimension()!=mdim)
5433 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5435 return const_cast<DataArrayDouble *>(ret);
5439 * Sets the family field of a given relative dimension.
5440 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5441 * the family field is set.
5442 * \param [in] famArr - the array of the family field.
5443 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5444 * \throw If \a famArr has an invalid size.
5446 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5448 if(meshDimRelToMaxExt==1)
5455 DataArrayDouble *coo(_coords);
5457 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5458 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5459 _fam_coords.takeRef(famArr);
5462 if(meshDimRelToMaxExt>1)
5463 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5464 int traducedRk=-meshDimRelToMaxExt;
5465 if(traducedRk>=(int)_ms.size())
5466 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5467 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5468 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5469 return _ms[traducedRk]->setFamilyArr(famArr);
5473 * Sets the optional numbers of mesh entities of a given dimension.
5474 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5475 * \param [in] renumArr - the array of the numbers.
5476 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5477 * \throw If \a renumArr has an invalid size.
5479 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5481 if(meshDimRelToMaxExt==1)
5485 _num_coords.nullify();
5486 _rev_num_coords.nullify();
5489 if(_coords.isNull())
5490 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5491 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5492 _num_coords.takeRef(renumArr);
5495 if(meshDimRelToMaxExt>1)
5496 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5497 int traducedRk=-meshDimRelToMaxExt;
5498 if(traducedRk>=(int)_ms.size())
5499 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5500 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5501 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5502 return _ms[traducedRk]->setRenumArr(renumArr);
5506 * Sets the optional names of mesh entities of a given dimension.
5507 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5508 * \param [in] nameArr - the array of the names.
5509 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5510 * \throw If \a nameArr has an invalid size.
5512 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5514 if(meshDimRelToMaxExt==1)
5521 DataArrayDouble *coo(_coords);
5523 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5524 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5525 _name_coords.takeRef(nameArr);
5528 if(meshDimRelToMaxExt>1)
5529 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5530 int traducedRk=-meshDimRelToMaxExt;
5531 if(traducedRk>=(int)_ms.size())
5532 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5533 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5534 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5535 return _ms[traducedRk]->setNameArr(nameArr);
5538 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
5540 if(meshDimRelToMaxExt!=1)
5541 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5543 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5544 _global_num_coords.takeRef(globalNumArr);
5547 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5549 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5550 if((const MEDFileUMeshSplitL1 *)(*it))
5551 (*it)->synchronizeTinyInfo(*this);
5555 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5557 void MEDFileUMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
5559 DataArrayIdType *arr=_fam_coords;
5561 arr->changeValue(oldId,newId);
5562 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5564 MEDFileUMeshSplitL1 *sp=(*it);
5567 sp->changeFamilyIdArr(oldId,newId);
5572 std::list< MCAuto<DataArrayIdType> > MEDFileUMesh::getAllNonNullFamilyIds() const
5574 std::list< MCAuto<DataArrayIdType> > ret;
5575 const DataArrayIdType *da(_fam_coords);
5577 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5578 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5580 const MEDFileUMeshSplitL1 *elt(*it);
5583 da=elt->getFamilyField();
5585 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5591 void MEDFileUMesh::computeRevNum() const
5593 if(_num_coords.isNotNull())
5596 mcIdType maxValue=_num_coords->getMaxValue(pos);
5597 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5601 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5603 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5606 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5608 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5609 ret.push_back((const DataArrayIdType *)_fam_nodes);
5610 ret.push_back((const DataArrayIdType *)_num_nodes);
5611 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5612 ret.push_back((const DataArrayIdType *)_fam_cells);
5613 ret.push_back((const DataArrayIdType *)_num_cells);
5614 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5615 ret.push_back((const DataArrayIdType *)_fam_faces);
5616 ret.push_back((const DataArrayIdType *)_num_faces);
5617 ret.push_back((const DataArrayIdType *)_rev_num_nodes);
5618 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5619 ret.push_back((const DataArrayIdType *)_rev_num_cells);
5620 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5624 mcIdType MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5626 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5627 if((const DataArrayIdType *)_fam_nodes)
5629 mcIdType val=_fam_nodes->getMaxValue(tmp);
5630 ret=std::max(ret,std::abs(val));
5632 if((const DataArrayIdType *)_fam_cells)
5634 mcIdType val=_fam_cells->getMaxValue(tmp);
5635 ret=std::max(ret,std::abs(val));
5637 if((const DataArrayIdType *)_fam_faces)
5639 mcIdType val=_fam_faces->getMaxValue(tmp);
5640 ret=std::max(ret,std::abs(val));
5645 mcIdType MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5647 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5648 if((const DataArrayIdType *)_fam_nodes)
5650 mcIdType val=_fam_nodes->getMaxValue(tmp);
5651 ret=std::max(ret,val);
5653 if((const DataArrayIdType *)_fam_cells)
5655 mcIdType val=_fam_cells->getMaxValue(tmp);
5656 ret=std::max(ret,val);
5658 if((const DataArrayIdType *)_fam_faces)
5660 mcIdType val=_fam_faces->getMaxValue(tmp);
5661 ret=std::max(ret,val);
5666 mcIdType MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5668 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
5669 if((const DataArrayIdType *)_fam_nodes)
5671 mcIdType val=_fam_nodes->getMinValue(tmp);
5672 ret=std::min(ret,val);
5674 if((const DataArrayIdType *)_fam_cells)
5676 mcIdType val=_fam_cells->getMinValue(tmp);
5677 ret=std::min(ret,val);
5679 if((const DataArrayIdType *)_fam_faces)
5681 mcIdType val=_fam_faces->getMinValue(tmp);
5682 ret=std::min(ret,val);
5687 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5689 if(!MEDFileMesh::isEqual(other,eps,what))
5691 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5694 what="Mesh types differ ! This is structured and other is NOT !";
5697 const DataArrayIdType *famc1=_fam_nodes;
5698 const DataArrayIdType *famc2=otherC->_fam_nodes;
5699 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5701 what="Mismatch of families arr on nodes ! One is defined and not other !";
5706 bool ret=famc1->isEqual(*famc2);
5709 what="Families arr on nodes differ !";
5714 famc2=otherC->_fam_cells;
5715 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5717 what="Mismatch of families arr on cells ! One is defined and not other !";
5722 bool ret=famc1->isEqual(*famc2);
5725 what="Families arr on cells differ !";
5730 famc2=otherC->_fam_faces;
5731 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5733 what="Mismatch of families arr on faces ! One is defined and not other !";
5738 bool ret=famc1->isEqual(*famc2);
5741 what="Families arr on faces differ !";
5746 famc2=otherC->_num_nodes;
5747 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5749 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5754 bool ret=famc1->isEqual(*famc2);
5757 what="Numbering arr on nodes differ !";
5762 famc2=otherC->_num_cells;
5763 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5765 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5770 bool ret=famc1->isEqual(*famc2);
5773 what="Numbering arr on cells differ !";
5778 famc2=otherC->_num_faces;
5779 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5781 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5786 bool ret=famc1->isEqual(*famc2);
5789 what="Numbering arr on faces differ !";
5793 const DataArrayAsciiChar *d1=_names_cells;
5794 const DataArrayAsciiChar *d2=otherC->_names_cells;
5795 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5797 what="Mismatch of naming arr on cells ! One is defined and not other !";
5802 bool ret=d1->isEqual(*d2);
5805 what="Naming arr on cells differ !";
5810 d2=otherC->_names_faces;
5811 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5813 what="Mismatch of naming arr on faces ! One is defined and not other !";
5818 bool ret=d1->isEqual(*d2);
5821 what="Naming arr on faces differ !";
5826 d2=otherC->_names_nodes;
5827 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5829 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5834 bool ret=d1->isEqual(*d2);
5837 what="Naming arr on nodes differ !";
5844 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5846 MEDFileMesh::clearNonDiscrAttributes();
5847 const DataArrayIdType *tmp=_fam_nodes;
5849 (const_cast<DataArrayIdType *>(tmp))->setName("");
5852 (const_cast<DataArrayIdType *>(tmp))->setName("");
5855 (const_cast<DataArrayIdType *>(tmp))->setName("");
5858 (const_cast<DataArrayIdType *>(tmp))->setName("");
5861 (const_cast<DataArrayIdType *>(tmp))->setName("");
5864 (const_cast<DataArrayIdType *>(tmp))->setName("");
5868 * Returns ids of mesh entities contained in given families of a given dimension.
5869 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5871 * \param [in] fams - the names of the families of interest.
5872 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5873 * returned instead of ids.
5874 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
5875 * numbers, if available and required, of mesh entities of the families. The caller
5876 * is to delete this array using decrRef() as it is no more needed.
5877 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5879 DataArrayIdType *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5881 std::vector<mcIdType> famIds(getFamiliesIds(fams));
5882 switch(meshDimRelToMaxExt)
5886 if((const DataArrayIdType *)_fam_nodes)
5888 MCAuto<DataArrayIdType> da;
5890 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5892 da=_fam_nodes->findIdsEqualList(0,0);
5894 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5899 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5904 if((const DataArrayIdType *)_fam_cells)
5906 MCAuto<DataArrayIdType> da;
5908 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5910 da=_fam_cells->findIdsEqualList(0,0);
5912 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5917 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5922 if((const DataArrayIdType *)_fam_faces)
5924 MCAuto<DataArrayIdType> da;
5926 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5928 da=_fam_faces->findIdsEqualList(0,0);
5930 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5935 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5939 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5941 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5945 * Sets the family field of a given relative dimension.
5946 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5947 * the family field is set.
5948 * \param [in] famArr - the array of the family field.
5949 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5950 * \throw If \a famArr has an invalid size.
5951 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5953 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5955 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5957 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5958 switch(meshDimRelToMaxExt)
5962 mcIdType nbCells(mesh->getNumberOfCells());
5964 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5970 mcIdType nbNodes(mesh->getNumberOfNodes());
5972 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5978 mcIdType nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5980 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5985 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5992 * Sets the optional numbers of mesh entities of a given dimension.
5993 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5994 * \param [in] renumArr - the array of the numbers.
5995 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5996 * \throw If \a renumArr has an invalid size.
5997 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5999 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
6001 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
6003 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
6004 switch(meshDimRelToMaxExt)
6008 mcIdType nbCells=mesh->getNumberOfCells();
6009 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
6010 _num_cells=renumArr;
6015 mcIdType nbNodes=mesh->getNumberOfNodes();
6016 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
6017 _num_nodes=renumArr;
6022 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6023 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
6024 _num_faces=renumArr;
6028 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
6031 renumArr->incrRef();
6035 * Sets the optional names of mesh entities of a given dimension.
6036 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6037 * \param [in] nameArr - the array of the names.
6038 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6039 * \throw If \a nameArr has an invalid size.
6041 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
6043 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
6045 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
6046 switch(meshDimRelToMaxExt)
6050 mcIdType nbCells=mesh->getNumberOfCells();
6051 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
6052 _names_cells=nameArr;
6057 mcIdType nbNodes=mesh->getNumberOfNodes();
6058 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
6059 _names_nodes=nameArr;
6064 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6065 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
6066 _names_faces=nameArr;
6070 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6076 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
6078 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
6082 * Adds a group of nodes to \a this mesh.
6083 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6084 * The ids should be sorted and different each other (MED file norm).
6086 * \warning this method can alter default "FAMILLE_ZERO" family.
6087 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6089 * \throw If the node coordinates array is not set.
6090 * \throw If \a ids == \c NULL.
6091 * \throw If \a ids->getName() == "".
6092 * \throw If \a ids does not respect the MED file norm.
6093 * \throw If a group with name \a ids->getName() already exists.
6095 void MEDFileStructuredMesh::addNodeGroup(const DataArrayIdType *ids)
6101 * Adds a group of nodes/cells/faces/edges to \a this mesh.
6103 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6104 * The ids should be sorted and different each other (MED file norm).
6106 * \warning this method can alter default "FAMILLE_ZERO" family.
6107 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6109 * \throw If the node coordinates array is not set.
6110 * \throw If \a ids == \c NULL.
6111 * \throw If \a ids->getName() == "".
6112 * \throw If \a ids does not respect the MED file norm.
6113 * \throw If a group with name \a ids->getName() already exists.
6115 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
6117 DataArrayIdType *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
6118 addGroupUnderground(false,ids,fam);
6123 * Returns the family field for mesh entities of a given dimension.
6124 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6125 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6126 * each mesh entity belongs to. It can be \c NULL.
6127 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6129 const DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
6131 switch(meshDimRelToMaxExt)
6140 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6145 * Returns the family field for mesh entities of a given dimension.
6146 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6147 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6148 * each mesh entity belongs to. It can be \c NULL.
6149 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6151 DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
6153 switch(meshDimRelToMaxExt)
6162 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6167 * Returns the optional numbers of mesh entities of a given dimension.
6168 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6169 * \return const DataArrayIdType * - the array of the entity numbers.
6170 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6171 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6173 const DataArrayIdType *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
6175 switch(meshDimRelToMaxExt)
6184 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6189 * Returns the optional numbers of mesh entities of a given dimension transformed using
6190 * DataArrayIdType::invertArrayN2O2O2N().
6191 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6192 * \return const DataArrayIdType * - the array of the entity numbers transformed using
6193 * DataArrayIdType::invertArrayN2O2O2N().
6194 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6195 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6197 const DataArrayIdType *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
6199 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
6200 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
6201 if(meshDimRelToMaxExt==0)
6203 if((const DataArrayIdType *)_num_cells)
6206 mcIdType maxValue=_num_cells->getMaxValue(pos);
6207 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
6208 return _rev_num_cells;
6211 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
6215 if((const DataArrayIdType *)_num_nodes)
6218 mcIdType maxValue=_num_nodes->getMaxValue(pos);
6219 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
6220 return _rev_num_nodes;
6223 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6227 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6229 switch(meshDimRelToMaxExt)
6232 return _names_cells;
6234 return _names_nodes;
6236 return _names_faces;
6238 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6242 MCAuto<DataArrayIdType> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6244 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6248 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6249 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6251 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6253 std::vector<int> ret(1);
6258 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6259 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6261 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6263 std::vector<int> ret(2);
6269 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6271 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6273 std::vector<int> ret;
6274 const DataArrayIdType *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6285 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6287 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6289 std::vector<int> ret;
6290 const DataArrayIdType *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6301 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6303 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6305 std::vector<int> ret;
6306 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6317 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6319 bool MEDFileStructuredMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
6321 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6325 void MEDFileStructuredMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
6327 DataArrayIdType *arr=_fam_nodes;
6329 arr->changeValue(oldId,newId);
6332 arr->changeValue(oldId,newId);
6335 arr->changeValue(oldId,newId);
6338 std::list< MCAuto<DataArrayIdType> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6340 std::list< MCAuto<DataArrayIdType> > ret;
6341 const DataArrayIdType *da(_fam_nodes);
6343 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6346 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6349 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6353 void MEDFileStructuredMesh::deepCpyAttributes()
6355 if((const DataArrayIdType*)_fam_nodes)
6356 _fam_nodes=_fam_nodes->deepCopy();
6357 if((const DataArrayIdType*)_num_nodes)
6358 _num_nodes=_num_nodes->deepCopy();
6359 if((const DataArrayAsciiChar*)_names_nodes)
6360 _names_nodes=_names_nodes->deepCopy();
6361 if((const DataArrayIdType*)_fam_cells)
6362 _fam_cells=_fam_cells->deepCopy();
6363 if((const DataArrayIdType*)_num_cells)
6364 _num_cells=_num_cells->deepCopy();
6365 if((const DataArrayAsciiChar*)_names_cells)
6366 _names_cells=_names_cells->deepCopy();
6367 if((const DataArrayIdType*)_fam_faces)
6368 _fam_faces=_fam_faces->deepCopy();
6369 if((const DataArrayIdType*)_num_faces)
6370 _num_faces=_num_faces->deepCopy();
6371 if((const DataArrayAsciiChar*)_names_faces)
6372 _names_faces=_names_faces->deepCopy();
6373 if((const DataArrayIdType*)_rev_num_nodes)
6374 _rev_num_nodes=_rev_num_nodes->deepCopy();
6375 if((const DataArrayIdType*)_rev_num_cells)
6376 _rev_num_cells=_rev_num_cells->deepCopy();
6380 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6382 * \return a pointer to cartesian mesh that need to be managed by the caller.
6383 * \warning the returned pointer has to be managed by the caller.
6387 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6388 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6389 * \param [in] renum - it must be \c false.
6390 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6391 * delete using decrRef() as it is no more needed.
6393 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6397 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6398 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6399 switch(meshDimRelToMax)
6405 return const_cast<MEDCouplingStructuredMesh *>(m);
6410 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6411 buildMinusOneImplicitPartIfNeeded();
6412 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6418 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6423 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
6424 * To include nodes, call getFamsNonEmptyLevelsExt() method.
6425 * \param [in] fams - the name of the family of interest.
6426 * \return std::vector<int> - a sequence of the relative dimensions.
6428 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6430 std::vector<mcIdType> lvls;
6431 std::vector<mcIdType> famIds(getFamiliesIds(fams));
6432 const DataArrayIdType *famCells(_fam_cells),*famFaces(_fam_faces);
6433 if(famCells && famCells->presenceOfValue(famIds))
6435 if(famFaces && famFaces->presenceOfValue(famIds))
6441 * Returns all relative mesh levels (including nodes) where given families are defined.
6442 * \param [in] fams - the names of the families of interest.
6443 * \return std::vector<int> - a sequence of the relative dimensions.
6445 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6447 std::vector<mcIdType> lvls(getFamsNonEmptyLevels(fams));
6448 std::vector<mcIdType> famIds(getFamiliesIds(fams));
6449 const DataArrayIdType *famNodes(_fam_nodes);
6450 if(famNodes && famNodes->presenceOfValue(famIds))
6456 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6457 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6458 * \return mcIdType - the number of entities.
6459 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6461 mcIdType MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6463 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6465 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6466 switch(meshDimRelToMaxExt)
6469 return cmesh->getNumberOfCells();
6471 return cmesh->getNumberOfNodes();
6473 return cmesh->getNumberOfCellsOfSubLevelMesh();
6475 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6479 mcIdType MEDFileStructuredMesh::getNumberOfNodes() const
6481 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6483 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6484 return cmesh->getNumberOfNodes();
6487 mcIdType MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6489 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6491 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6492 switch(meshDimRelToMaxExt)
6495 return cmesh->getNumberOfCells();
6497 return cmesh->getNumberOfCellsOfSubLevelMesh();
6499 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6503 bool MEDFileStructuredMesh::hasImplicitPart() const
6509 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6511 mcIdType MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6513 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6514 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6517 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6518 if(cm.getReverseExtrudedType()!=gt)
6519 throw INTERP_KERNEL::Exception(MSG);
6520 buildImplicitPart();
6521 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6525 if(gt!=zeFaceMesh->getCellModelEnum())
6526 throw INTERP_KERNEL::Exception(MSG);
6527 return zeFaceMesh->getNumberOfCells();
6531 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6533 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6535 buildImplicitPart();
6538 void MEDFileStructuredMesh::buildImplicitPart() const
6540 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6542 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6543 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6546 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6548 _faces_if_necessary=0;
6552 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6553 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6555 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6557 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6560 return _faces_if_necessary;
6563 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6565 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6567 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6568 switch(meshDimRelToMax)
6572 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6577 int mdim(cmesh->getMeshDimension());
6579 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6580 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6584 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6588 mcIdType MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6590 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6593 return getNumberOfCellsAtLevel(0);
6596 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6598 if(st.getNumberOfItems()!=1)
6599 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 !");
6600 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6601 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6602 if(getNumberOfNodes()!=(mcIdType)nodesFetched.size())
6603 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6604 if(st[0].getPflName().empty())
6606 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6609 const DataArrayIdType *arr(globs->getProfile(st[0].getPflName()));
6610 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6611 mcIdType sz(ToIdType(nodesFetched.size()));
6612 for(const mcIdType *work=arr->begin();work!=arr->end();work++)
6614 std::vector<mcIdType> conn;
6615 cmesh->getNodeIdsOfCell(*work,conn);
6616 for(std::vector<mcIdType>::const_iterator it=conn.begin();it!=conn.end();it++)
6617 if(*it>=0 && *it<sz)
6618 nodesFetched[*it]=true;
6620 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6624 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6626 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6630 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6631 MCAuto<DataArrayIdType>& famCells, MCAuto<DataArrayIdType>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6633 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6634 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6635 mcIdType nbOfElt(0);
6636 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6639 if(!mrs || mrs->isCellFamilyFieldReading())
6641 MCAuto<DataArrayMedInt> miFamCells=DataArrayMedInt::New();
6642 miFamCells->alloc(nbOfElt,1);
6643 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miFamCells->getPointer()));
6644 famCells = FromMedIntArray<mcIdType>( miFamCells );
6647 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6650 if(!mrs || mrs->isCellNumFieldReading())
6652 MCAuto<DataArrayMedInt> miNumCells=DataArrayMedInt::New();
6653 miNumCells->alloc(nbOfElt,1);
6654 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miNumCells->getPointer()));
6655 numCells = FromMedIntArray<mcIdType>( miNumCells );
6658 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6661 if(!mrs || mrs->isCellNameFieldReading())
6663 namesCells=DataArrayAsciiChar::New();
6664 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6665 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6666 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6671 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6673 setName(strm->getName());
6674 setDescription(strm->getDescription());
6675 setUnivName(strm->getUnivName());
6676 setIteration(strm->getIteration());
6677 setOrder(strm->getOrder());
6678 setTimeValue(strm->getTime());
6679 setTimeUnit(strm->getTimeUnit());
6680 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6681 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6682 mcIdType nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6685 if(!mrs || mrs->isNodeFamilyFieldReading())
6687 mcIdType nbNodes(getNumberOfNodes());
6689 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6690 MCAuto<DataArrayMedInt> miFamNodes=DataArrayMedInt::New();
6691 miFamNodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6692 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...
6693 miFamNodes->fillWithZero();
6694 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miFamNodes->getPointer()));
6695 _fam_nodes = FromMedIntArray<mcIdType>( miFamNodes );
6698 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6701 if(!mrs || mrs->isNodeNumFieldReading())
6703 MCAuto<DataArrayMedInt> miNumNodes=DataArrayMedInt::New();
6704 miNumNodes->alloc(nbOfElt,1);
6705 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miNumNodes->getPointer()));
6706 _num_nodes = FromMedIntArray<mcIdType>( miNumNodes );
6709 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6712 if(!mrs || mrs->isNodeNameFieldReading())
6714 _names_nodes=DataArrayAsciiChar::New();
6715 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6716 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6717 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6720 int meshDim(getStructuredMesh()->getMeshDimension());
6721 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6723 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6726 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6728 int meshDim(getStructuredMesh()->getMeshDimension());
6729 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6731 if((const DataArrayIdType *)_fam_cells)
6732 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_fam_cells->getNumberOfTuples()),ToMedIntArray(_fam_cells)->getConstPointer()));
6733 if((const DataArrayIdType *)_fam_faces)
6734 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_fam_faces->getNumberOfTuples()),ToMedIntArray(_fam_faces)->getConstPointer()));
6735 if((const DataArrayIdType *)_fam_nodes)
6736 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_fam_nodes->getNumberOfTuples()),ToMedIntArray(_fam_nodes)->getConstPointer()));
6737 if((const DataArrayIdType *)_num_cells)
6738 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_num_cells->getNumberOfTuples()),ToMedIntArray(_num_cells)->getConstPointer()));
6739 if((const DataArrayIdType *)_num_faces)
6740 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_num_faces->getNumberOfTuples()),ToMedIntArray(_num_faces)->getConstPointer()));
6741 if((const DataArrayIdType *)_num_nodes)
6742 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_num_nodes->getNumberOfTuples()),ToMedIntArray(_num_nodes)->getConstPointer()));
6743 if((const DataArrayAsciiChar *)_names_cells)
6745 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6747 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6748 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6749 throw INTERP_KERNEL::Exception(oss.str().c_str());
6751 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_names_cells->getNumberOfTuples()),_names_cells->getConstPointer()));
6753 if((const DataArrayAsciiChar *)_names_faces)
6755 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6757 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6758 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6759 throw INTERP_KERNEL::Exception(oss.str().c_str());
6761 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_names_faces->getNumberOfTuples()),_names_faces->getConstPointer()));
6763 if((const DataArrayAsciiChar *)_names_nodes)
6765 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6767 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6768 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6769 throw INTERP_KERNEL::Exception(oss.str().c_str());
6771 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_names_nodes->getNumberOfTuples()),_names_nodes->getConstPointer()));
6774 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6778 * Returns an empty instance of MEDFileCMesh.
6779 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6780 * mesh using decrRef() as it is no more needed.
6782 MEDFileCMesh *MEDFileCMesh::New()
6784 return new MEDFileCMesh;
6788 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6789 * file. The first mesh in the file is loaded.
6790 * \param [in] fileName - the name of MED file to read.
6791 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6792 * mesh using decrRef() as it is no more needed.
6793 * \throw If the file is not readable.
6794 * \throw If there is no meshes in the file.
6795 * \throw If the mesh in the file is not a Cartesian one.
6797 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6799 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6800 return New(fid,mrs);
6803 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6805 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6809 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6810 * file. The mesh to load is specified by its name and numbers of a time step and an
6812 * \param [in] fileName - the name of MED file to read.
6813 * \param [in] mName - the name of the mesh to read.
6814 * \param [in] dt - the number of a time step.
6815 * \param [in] it - the number of an iteration.
6816 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6817 * mesh using decrRef() as it is no more needed.
6818 * \throw If the file is not readable.
6819 * \throw If there is no mesh with given attributes in the file.
6820 * \throw If the mesh in the file is not a Cartesian one.
6822 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6824 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6825 return New(fid,mName,dt,it,mrs);
6828 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6830 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6833 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6835 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6838 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6840 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6841 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6846 * Returns the dimension on cells in \a this mesh.
6847 * \return int - the mesh dimension.
6848 * \throw If there are no cells in this mesh.
6850 int MEDFileCMesh::getMeshDimension() const
6852 if(!((const MEDCouplingCMesh*)_cmesh))
6853 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6854 return _cmesh->getMeshDimension();
6858 * Returns the dimension on nodes in \a this mesh.
6859 * \return int - the space dimension.
6860 * \throw If there are no cells in this mesh.
6862 int MEDFileCMesh::getSpaceDimension() const
6864 if(!((const MEDCouplingCMesh*)_cmesh))
6865 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6866 return _cmesh->getSpaceDimension();
6870 * Returns a string describing \a this mesh.
6871 * \return std::string - the mesh information string.
6873 std::string MEDFileCMesh::simpleRepr() const
6875 return MEDFileStructuredMesh::simpleRepr();
6879 * Returns a full textual description of \a this mesh.
6880 * \return std::string - the string holding the mesh description.
6882 std::string MEDFileCMesh::advancedRepr() const
6884 return simpleRepr();
6887 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6889 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6893 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6895 return new MEDFileCMesh;
6898 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6900 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6901 ret->deepCpyEquivalences(*this);
6902 if((const MEDCouplingCMesh*)_cmesh)
6903 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6904 ret->deepCpyAttributes();
6909 * Checks if \a this and another mesh are equal.
6910 * \param [in] other - the mesh to compare with.
6911 * \param [in] eps - a precision used to compare real values.
6912 * \param [in,out] what - the string returning description of unequal data.
6913 * \return bool - \c true if the meshes are equal, \c false, else.
6915 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6917 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6919 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6922 what="Mesh types differ ! This is cartesian and other is NOT !";
6925 clearNonDiscrAttributes();
6926 otherC->clearNonDiscrAttributes();
6927 const MEDCouplingCMesh *coo1=_cmesh;
6928 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6929 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6931 what="Mismatch of cartesian meshes ! One is defined and not other !";
6936 bool ret=coo1->isEqual(coo2,eps);
6939 what="cartesian meshes differ !";
6947 * Clears redundant attributes of incorporated data arrays.
6949 void MEDFileCMesh::clearNonDiscrAttributes() const
6951 MEDFileStructuredMesh::clearNonDiscrAttributes();
6952 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6955 MEDFileCMesh::MEDFileCMesh()
6959 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6962 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6964 catch(INTERP_KERNEL::Exception& e)
6969 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6971 MEDCoupling::MEDCouplingMeshType meshType;
6974 MEDCoupling::MEDCouplingAxisType axType;
6975 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6976 if(meshType!=CARTESIAN)
6978 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6979 throw INTERP_KERNEL::Exception(oss.str().c_str());
6981 MEDFileCMeshL2 loaderl2;
6982 loaderl2.loadAll(fid,mid,mName,dt,it);
6983 setAxisType(axType);
6984 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6987 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6991 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6992 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6994 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6996 synchronizeTinyInfoOnLeaves();
7000 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
7002 synchronizeTinyInfoOnLeaves();
7007 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
7008 * \param [in] m - the new MEDCouplingCMesh to refer to.
7009 * \throw If the name or the description of \a this mesh and \a m are not empty and are
7012 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
7014 dealWithTinyInfo(m);
7020 MEDFileMesh *MEDFileCMesh::cartesianize() const
7022 if(getAxisType()==AX_CART)
7025 return const_cast<MEDFileCMesh *>(this);
7029 const MEDCouplingCMesh *cmesh(getMesh());
7031 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7032 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
7033 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
7034 clmesh->setCoords(coords);
7035 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
7036 ret->MEDFileStructuredMesh::operator=(*this);
7037 ret->setMesh(clmesh);
7038 ret->setAxisType(AX_CART);
7043 void MEDFileCMesh::writeMeshLL(med_idt fid) const
7045 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7046 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7047 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7048 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7049 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7050 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7051 int spaceDim(_cmesh->getSpaceDimension());
7052 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7053 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7054 for(int i=0;i<spaceDim;i++)
7056 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
7058 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7059 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
7060 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
7062 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7064 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7065 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
7066 for(int i=0;i<spaceDim;i++)
7068 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
7069 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,ToMedInt(da->getNumberOfTuples()),da->getConstPointer()));
7072 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7073 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7076 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
7078 const MEDCouplingCMesh *cmesh=_cmesh;
7081 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
7082 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
7083 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
7084 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
7087 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
7089 return new MEDFileCurveLinearMesh;
7092 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
7094 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
7097 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
7099 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7100 return New(fid,mrs);
7103 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7105 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7106 return New(fid,mName,dt,it,mrs);
7109 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7111 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
7114 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
7116 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
7119 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
7121 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
7122 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
7126 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
7128 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7132 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
7134 return new MEDFileCurveLinearMesh;
7137 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
7139 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7140 ret->deepCpyEquivalences(*this);
7141 if((const MEDCouplingCurveLinearMesh*)_clmesh)
7142 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
7143 ret->deepCpyAttributes();
7147 int MEDFileCurveLinearMesh::getMeshDimension() const
7149 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7150 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get mesh dimension because no mesh set !");
7151 return _clmesh->getMeshDimension();
7154 int MEDFileCurveLinearMesh::getSpaceDimension() const
7156 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7157 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get space dimension because no mesh set !");
7158 return _clmesh->getSpaceDimension();
7161 std::string MEDFileCurveLinearMesh::simpleRepr() const
7163 return MEDFileStructuredMesh::simpleRepr();
7166 std::string MEDFileCurveLinearMesh::advancedRepr() const
7168 return simpleRepr();
7171 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7173 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7175 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
7178 what="Mesh types differ ! This is curve linear and other is NOT !";
7181 clearNonDiscrAttributes();
7182 otherC->clearNonDiscrAttributes();
7183 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
7184 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
7185 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7187 what="Mismatch of curve linear meshes ! One is defined and not other !";
7192 bool ret=coo1->isEqual(coo2,eps);
7195 what="curve linear meshes differ !";
7202 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
7204 MEDFileStructuredMesh::clearNonDiscrAttributes();
7205 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
7208 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
7210 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
7213 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
7214 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
7215 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
7216 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
7219 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
7221 synchronizeTinyInfoOnLeaves();
7225 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
7227 dealWithTinyInfo(m);
7233 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
7235 if(getAxisType()==AX_CART)
7238 return const_cast<MEDFileCurveLinearMesh *>(this);
7242 const MEDCouplingCurveLinearMesh *mesh(getMesh());
7244 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7245 const DataArrayDouble *coords(mesh->getCoords());
7247 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
7248 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7249 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
7250 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7251 mesh2->setCoords(coordsCart);
7252 ret->setMesh(mesh2);
7253 ret->setAxisType(AX_CART);
7258 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7260 synchronizeTinyInfoOnLeaves();
7264 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7268 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7271 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7273 catch(INTERP_KERNEL::Exception& e)
7278 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7280 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7281 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7282 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7283 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7284 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7285 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7286 int spaceDim=_clmesh->getSpaceDimension();
7287 int meshDim=_clmesh->getMeshDimension();
7288 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7289 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7290 const DataArrayDouble *coords=_clmesh->getCoords();
7292 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7293 for(int i=0;i<spaceDim;i++)
7295 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7297 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7298 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
7299 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
7301 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7303 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7304 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7305 std::vector<mcIdType> nodeGridSt=_clmesh->getNodeGridStructure();
7306 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,ToMedIntArray(nodeGridSt)->getConstPointer()));
7308 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,ToMedInt(coords->getNumberOfTuples()),coords->begin()));
7310 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7311 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7314 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7316 MEDCoupling::MEDCouplingMeshType meshType;
7319 MEDCoupling::MEDCouplingAxisType axType;
7320 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7321 setAxisType(axType);
7322 if(meshType!=CURVE_LINEAR)
7324 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7325 throw INTERP_KERNEL::Exception(oss.str().c_str());
7327 MEDFileCLMeshL2 loaderl2;
7328 loaderl2.loadAll(fid,mid,mName,dt,it);
7329 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7332 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7335 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7337 return new MEDFileMeshMultiTS;
7340 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7342 return new MEDFileMeshMultiTS(fid);
7345 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7347 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7351 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7353 return new MEDFileMeshMultiTS(fid,mName);
7356 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7358 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7359 return New(fid,mName);
7362 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7364 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7365 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7367 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7368 if((const MEDFileMesh *)*it)
7369 meshOneTs[i]=(*it)->deepCopy();
7370 ret->_mesh_one_ts=meshOneTs;
7374 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7376 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7379 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7381 std::vector<const BigMemoryObject *> ret;
7382 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7383 ret.push_back((const MEDFileMesh *)*it);
7387 std::string MEDFileMeshMultiTS::getName() const
7389 if(_mesh_one_ts.empty())
7390 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7391 return _mesh_one_ts[0]->getName();
7394 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7396 std::string oldName(getName());
7397 std::vector< std::pair<std::string,std::string> > v(1);
7398 v[0].first=oldName; v[0].second=newMeshName;
7402 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7405 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7407 MEDFileMesh *cur(*it);
7409 ret=cur->changeNames(modifTab) || ret;
7414 void MEDFileMeshMultiTS::cartesianizeMe()
7416 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7418 MEDFileMesh *cur(*it);
7421 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7427 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7429 if(_mesh_one_ts.empty())
7430 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7431 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7434 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7437 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7438 _mesh_one_ts.resize(1);
7439 mesh1TimeStep->incrRef();
7440 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7441 _mesh_one_ts[0]=mesh1TimeStep;
7444 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7446 if ( MEDFileMesh* m = getOneTimeStep() )
7447 return m->getJoints();
7452 * \brief Set Joints that are common to all time-stamps
7454 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7456 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7458 (*it)->setJoints( joints );
7462 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7464 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7465 if((*it).isNotNull())
7466 if((*it)->presenceOfStructureElements())
7471 void MEDFileMeshMultiTS::killStructureElements()
7473 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7474 if((*it).isNotNull())
7475 (*it)->killStructureElements();
7478 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7480 MEDFileJoints *joints(getJoints());
7481 bool jointsWritten(false);
7483 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7485 if ( jointsWritten )
7486 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7488 jointsWritten = true;
7490 (*it)->copyOptionsFrom(*this);
7491 (*it)->writeLL(fid);
7494 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7497 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7499 MEDFileJoints *joints(0);
7500 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7502 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7503 joints = getOneTimeStep()->getJoints();
7505 _mesh_one_ts.clear(); //for the moment to be improved
7506 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7509 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7513 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7516 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7519 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7520 throw INTERP_KERNEL::Exception(oss.str().c_str());
7523 MEDCoupling::MEDCouplingMeshType meshType;
7525 MEDCoupling::MEDCouplingAxisType dummy3;
7526 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7527 loadFromFile(fid,ms.front());
7529 catch(INTERP_KERNEL::Exception& e)
7534 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7537 loadFromFile(fid,mName);
7539 catch(INTERP_KERNEL::Exception& e)
7544 MEDFileMeshes *MEDFileMeshes::New()
7546 return new MEDFileMeshes;
7549 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7551 return new MEDFileMeshes(fid);
7554 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7556 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7560 void MEDFileMeshes::writeLL(med_idt fid) const
7562 checkConsistencyLight();
7563 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7565 (*it)->copyOptionsFrom(*this);
7566 (*it)->writeLL(fid);
7570 // MEDFileMeshes::writ checkConsistencyLight();
7572 int MEDFileMeshes::getNumberOfMeshes() const
7574 return (int)_meshes.size();
7577 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7579 return new MEDFileMeshesIterator(this);
7582 /** Return a borrowed reference (caller is not responsible) */
7583 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7585 if(i<0 || i>=(int)_meshes.size())
7587 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7588 throw INTERP_KERNEL::Exception(oss.str().c_str());
7590 return _meshes[i]->getOneTimeStep();
7593 /** Return a borrowed reference (caller is not responsible) */
7594 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7596 std::vector<std::string> ms=getMeshesNames();
7597 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7600 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7601 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7602 throw INTERP_KERNEL::Exception(oss.str().c_str());
7604 return getMeshAtPos((int)std::distance(ms.begin(),it));
7607 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7609 std::vector<std::string> ret(_meshes.size());
7611 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7613 const MEDFileMeshMultiTS *f=(*it);
7616 ret[i]=f->getName();
7620 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7621 throw INTERP_KERNEL::Exception(oss.str().c_str());
7627 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7630 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7632 MEDFileMeshMultiTS *cur(*it);
7634 ret=cur->changeNames(modifTab) || ret;
7639 void MEDFileMeshes::cartesianizeMe()
7641 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7643 MEDFileMeshMultiTS *cur(*it);
7645 cur->cartesianizeMe();
7649 void MEDFileMeshes::resize(int newSize)
7651 _meshes.resize(newSize);
7654 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7657 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7658 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7659 elt->setOneTimeStep(mesh);
7660 _meshes.push_back(elt);
7663 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7666 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7667 if(i>=(int)_meshes.size())
7668 _meshes.resize(i+1);
7669 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7670 elt->setOneTimeStep(mesh);
7674 void MEDFileMeshes::destroyMeshAtPos(int i)
7676 if(i<0 || i>=(int)_meshes.size())
7678 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7679 throw INTERP_KERNEL::Exception(oss.str().c_str());
7681 _meshes.erase(_meshes.begin()+i);
7684 void MEDFileMeshes::loadFromFile(med_idt fid)
7686 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7688 _meshes.resize(ms.size());
7689 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7690 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7693 MEDFileMeshes::MEDFileMeshes()
7697 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7702 catch(INTERP_KERNEL::Exception& /*e*/)
7706 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7708 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7710 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7711 if((const MEDFileMeshMultiTS *)*it)
7712 meshes[i]=(*it)->deepCopy();
7713 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7714 ret->_meshes=meshes;
7718 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7720 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7723 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7725 std::vector<const BigMemoryObject *> ret;
7726 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7727 ret.push_back((const MEDFileMeshMultiTS *)*it);
7731 std::string MEDFileMeshes::simpleRepr() const
7733 std::ostringstream oss;
7734 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7735 simpleReprWithoutHeader(oss);
7739 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7741 int nbOfMeshes=getNumberOfMeshes();
7742 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7743 std::vector<std::string> mns=getMeshesNames();
7744 for(int i=0;i<nbOfMeshes;i++)
7745 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7748 void MEDFileMeshes::checkConsistencyLight() const
7750 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7752 std::set<std::string> s;
7753 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7755 const MEDFileMeshMultiTS *elt=(*it);
7758 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7759 throw INTERP_KERNEL::Exception(oss.str().c_str());
7761 std::size_t sz=s.size();
7762 s.insert(std::string((*it)->getName()));
7765 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7766 throw INTERP_KERNEL::Exception(oss.str().c_str());
7771 bool MEDFileMeshes::presenceOfStructureElements() const
7773 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7774 if((*it).isNotNull())
7775 if((*it)->presenceOfStructureElements())
7780 void MEDFileMeshes::killStructureElements()
7782 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7783 if((*it).isNotNull())
7784 (*it)->killStructureElements();
7787 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7792 _nb_iter=ms->getNumberOfMeshes();
7796 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7800 MEDFileMesh *MEDFileMeshesIterator::nextt()
7802 if(_iter_id<_nb_iter)
7804 MEDFileMeshes *ms(_ms);
7806 return ms->getMeshAtPos(_iter_id++);
7814 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7816 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7817 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7819 if(geoType==MED_NO_GEOTYPE)
7820 return INTERP_KERNEL::NORM_ERROR;
7821 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7822 throw INTERP_KERNEL::Exception(oss.str());
7824 return typmai2[std::distance(typmai,pos)];
7827 med_geometry_type MEDFileMesh::ConvertToMEDFileGeoType(INTERP_KERNEL::NormalizedCellType geoType)
7829 INTERP_KERNEL::NormalizedCellType *pos(std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,geoType));
7830 if(pos==typmai2+MED_N_CELL_FIXED_GEO)
7832 THROW_IK_EXCEPTION("MEDFileMesh::ConvertToMEDFileGeoType : no entry for " << geoType);
7834 return typmai[std::distance(typmai2,pos)];
7837 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7845 case MED_NODE_ELEMENT:
7849 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7850 throw INTERP_KERNEL::Exception(oss.str());