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 const DataArrayIdType *arr=getFamilyFieldAtLevel(meshDimRelToMaxExt);
540 std::set<mcIdType> famIdsInUse(arr->begin(),arr->end());
542 for(auto it : _groups)
544 for(auto it2 : it.second)
546 auto it3 = _families.find( it2 );
547 mcIdType famIdToTest = (*it3).second;
548 if( famIdsInUse.find(famIdToTest) != famIdsInUse.end() )
550 ret.push_back( it.first );
559 * Returns all relative mesh levels (including nodes) where a given group is defined.
560 * \param [in] grp - the name of the group of interest.
561 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
563 std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
565 std::vector<std::string> fams(getFamiliesOnGroup(grp));
566 return getFamsNonEmptyLevelsExt(fams);
570 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
571 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
572 * \param [in] grps - a sequence of names of the groups of interest.
573 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
575 std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
577 std::vector<std::string> fams(getFamiliesOnGroups(grps));
578 return getFamsNonEmptyLevels(fams);
582 * Returns all relative mesh levels (including nodes) where given groups are defined.
583 * \param [in] grps - a sequence of names of the groups of interest.
584 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
586 std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
588 std::vector<std::string> fams(getFamiliesOnGroups(grps));
589 return getFamsNonEmptyLevelsExt(fams);
593 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
594 * To include nodes, call getGrpNonEmptyLevelsExt() method.
595 * \param [in] grp - the name of the group of interest.
596 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
598 std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
600 std::vector<std::string> fams(getFamiliesOnGroup(grp));
601 return getFamsNonEmptyLevels(fams);
605 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
606 * To include nodes, call getFamNonEmptyLevelsExt() method.
607 * \param [in] fam - the name of the family of interest.
608 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
610 std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
612 std::vector<std::string> fams(1,std::string(fam));
613 return getFamsNonEmptyLevels(fams);
617 * Returns all relative mesh levels (including nodes) where a given family is defined.
618 * \param [in] fam - the name of the family of interest.
619 * \return std::vector<mcIdType> - a sequence of the relative dimensions.
621 std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
623 std::vector<std::string> fams(1,std::string(fam));
624 return getFamsNonEmptyLevelsExt(fams);
627 std::string MEDFileMesh::GetMagicFamilyStr()
629 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
633 * Changes a name of every family, included in one group only, to be same as the group name.
634 * \throw If there are families with equal names in \a this mesh.
636 void MEDFileMesh::assignFamilyNameWithGroupName()
638 std::map<std::string, std::vector<std::string> > groups(_groups);
639 std::map<std::string,mcIdType> newFams;
640 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
642 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
643 if(grps.size()==1 && groups[grps[0]].size()==1)
645 if(newFams.find(grps[0])!=newFams.end())
647 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
648 throw INTERP_KERNEL::Exception(oss.str().c_str());
650 newFams[grps[0]]=(*it).second;
651 std::vector<std::string>& grps2=groups[grps[0]];
652 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
657 if(newFams.find((*it).first)!=newFams.end())
659 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
660 throw INTERP_KERNEL::Exception(oss.str().c_str());
662 newFams[(*it).first]=(*it).second;
670 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
672 * \return the removed groups.
674 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
676 std::vector<std::string> ret;
677 std::map<std::string, std::vector<std::string> > newGrps;
678 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
680 if((*it).second.empty())
681 ret.push_back((*it).first);
683 newGrps[(*it).first]=(*it).second;
690 void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name)
692 std::map<std::string, std::vector<std::string> >::iterator it(_groups.find(name));
693 std::vector<std::string> grps(getGroupsNames());
694 if(it==_groups.end())
696 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
697 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
698 throw INTERP_KERNEL::Exception(oss.str().c_str());
700 const std::vector<std::string> &famsOnGrp((*it).second);
701 std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(name));
702 const DataArrayIdType *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt));
705 MCAuto<DataArrayIdType> vals(famArr->getDifferentValues());
706 MCAuto<DataArrayIdType> famIds2(DataArrayIdType::NewFromStdVector(famIds));
707 MCAuto<DataArrayIdType> idsToKill(famIds2->buildIntersection(vals));
708 if(idsToKill->empty())
710 std::vector<std::string> newFamsOnGrp;
711 for(std::vector<std::string>::const_iterator itt=famsOnGrp.begin();itt!=famsOnGrp.end();itt++)
713 if(!idsToKill->presenceOfValue(getFamilyId(*itt)))
714 newFamsOnGrp.push_back(*itt);
716 (*it).second=newFamsOnGrp;
720 * Removes a group from \a this mesh.
721 * \param [in] name - the name of the group to remove.
722 * \throw If no group with such a \a name exists.
724 void MEDFileMesh::removeGroup(const std::string& name)
726 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(name);
727 std::vector<std::string> grps(getGroupsNames());
728 if(it==_groups.end())
730 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
731 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
732 throw INTERP_KERNEL::Exception(oss.str().c_str());
738 * Removes a family from \a this mesh.
739 * \param [in] name - the name of the family to remove.
740 * \throw If no family with such a \a name exists.
742 void MEDFileMesh::removeFamily(const std::string& name)
744 std::string oname(name);
745 std::map<std::string, mcIdType >::iterator it=_families.find(oname);
746 std::vector<std::string> fams=getFamiliesNames();
747 if(it==_families.end())
749 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
750 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
751 throw INTERP_KERNEL::Exception(oss.str().c_str());
754 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
756 std::vector<std::string>& v=(*it3).second;
757 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
764 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
765 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
766 * family field whatever its level. This method also suppresses the orphan families.
768 * \return - The list of removed groups names.
770 * \sa MEDFileMesh::removeOrphanFamilies.
772 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
774 removeOrphanFamilies();
775 return removeEmptyGroups();
779 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
780 * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified.
782 * \return - The list of removed families names.
783 * \sa MEDFileMesh::removeOrphanGroups , MEDFileMesh::removeFamiliesReferedByNoGroups
785 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
787 MCAuto<DataArrayIdType> allFamIdsInUse=computeAllFamilyIdsInUse();
788 std::vector<std::string> ret;
789 if(!((DataArrayIdType*)allFamIdsInUse))
791 ret=getFamiliesNames();
792 _families.clear(); _groups.clear();
795 std::map<std::string,mcIdType> famMap;
796 std::map<std::string, std::vector<std::string> > grps(_groups);
797 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
799 if(allFamIdsInUse->presenceOfValue((*it).second))
800 famMap[(*it).first]=(*it).second;
803 ret.push_back((*it).first);
804 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
805 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
807 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
808 std::vector<std::string>& famv=(*it3).second;
809 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
815 { _families=famMap; _groups=grps; }
820 * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever
821 * this family is orphan or not.
823 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
824 * \sa MEDFileMesh::removeOrphanFamilies
826 void MEDFileMesh::removeFamiliesReferedByNoGroups()
828 std::map<std::string,mcIdType> fams;
829 std::set<std::string> sfams;
830 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
831 sfams.insert((*it).first);
832 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
833 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
835 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
836 if(*it!=DFT_FAM_NAME)
837 _families.erase(*it);
841 * This method has no impact on groups. This method only works on families. This method firstly removes families not referred by any groups in \a this, then all unused entities
842 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
843 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
845 * This method also raises an exception if a family belonging to a group has also id 0 (which is not right in MED file format). You should never encounter this case using addGroup method.
847 * \sa MEDFileMesh::removeOrphanFamilies, MEDFileMesh::zipFamilies
849 void MEDFileMesh::rearrangeFamilies()
851 checkOrphanFamilyZero();
852 removeFamiliesReferedByNoGroups();
854 std::vector<int> levels(getNonEmptyLevelsExt());
855 std::set<mcIdType> idsRefed;
856 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
858 idsRefed.insert((*it).second);
861 if(!getGroupsOnFamily((*it).first).empty())
863 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Not orphan family \"" << (*it).first << "\" has id 0 ! This method may alterate groups in this for such a case !";
864 throw INTERP_KERNEL::Exception(oss.str());
868 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
870 const DataArrayIdType *fams(0);
873 fams=getFamilyFieldAtLevel(*it);
875 catch(INTERP_KERNEL::Exception& ) { }
878 std::vector<bool> v(fams->getNumberOfTuples(),false);
879 for(std::set<mcIdType>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
880 fams->switchOnTupleEqualTo(*pt,v);
881 MCAuto<DataArrayIdType> unfetchedIds(DataArrayIdType::BuildListOfSwitchedOff(v));
882 if(!unfetchedIds->empty())
884 MCAuto<DataArrayIdType> newFams(fams->deepCopy());
885 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
886 setFamilyFieldArr(*it,newFams);
889 removeOrphanFamilies();
893 * This method has no impact on existing groups. This method has only impact on families behind the groups.
894 * This method is especially useful for MED file structures having used too much families to define their groups and that need to be merged without modification of their groups.
895 * To zip families, firstly this method first removes families refered by no groups (see MEDFileMesh::removeFamiliesReferedByNoGroups), then this method puts together families lying on a same set of groups. If the set of families having same groups has a length higher than 1, the families are merged into a single family
896 * having the name of the first family appearing in family definition and with the corresponding family ID.
898 void MEDFileMesh::zipFamilies()
900 checkOrphanFamilyZero();
901 removeFamiliesReferedByNoGroups();
902 std::map< std::set<std::string> , std::vector<std::string> > setOfFamilies;
903 // firstly, store in setOfFamilies as key the common set of groups, and as value the families having such same set of groups
904 for(auto fam : _families)
906 std::vector<std::string> grps( this->getGroupsOnFamily( fam.first ) );
907 std::set<std::string> sgrps(grps.begin(),grps.end());
908 setOfFamilies[sgrps].push_back(fam.first);
911 std::map<std::string, std::vector<std::string> > newGroups(_groups);
912 std::map<std::string,mcIdType> newFams(_families);
913 std::vector<int> levels(getNonEmptyLevelsExt());
914 std::map<mcIdType, std::vector<mcIdType> > famIdsToSubstitute;
915 // iterate on all different set of groups
916 std::set<std::string> familiesToKill;
917 for(auto setOfCommonGrp : setOfFamilies)
919 if( setOfCommonGrp.second.size()<=1 )
921 for(auto fam=setOfCommonGrp.second.begin()+1 ; fam != setOfCommonGrp.second.end() ; fam++)
922 familiesToKill.insert(*fam);
924 // iterate on all different set of groups
925 for(auto setOfCommonGrp : setOfFamilies)
927 if( setOfCommonGrp.second.size()<=1 )
929 std::string newFamName(setOfCommonGrp.second[0]);
930 auto newFamID(_families[newFamName]);
931 for(auto grpToBeModified : setOfCommonGrp.first)
933 std::vector<std::string> newFamiliesForCurGrp(1,newFamName);
934 const std::vector<std::string>& familiesOnCurGrp(_groups[grpToBeModified]);
935 const std::vector<std::string>& familiesToZip(setOfCommonGrp.second);
936 std::for_each(familiesToZip.begin(),familiesToZip.end(),[&famIdsToSubstitute,this,newFamID](const std::string& elt) { famIdsToSubstitute[newFamID].push_back(this->getFamilyId(elt)); });
937 // for each family shared by the current group only keep those not sharing setOfCommonGrp.second
938 std::for_each(familiesOnCurGrp.begin(),familiesOnCurGrp.end(),[&familiesToKill,&newFamiliesForCurGrp](const std::string& elt)
939 { if( familiesToKill.find(elt) == familiesToKill.end() ) { newFamiliesForCurGrp.push_back(elt); } });
940 newGroups[grpToBeModified] = newFamiliesForCurGrp;
942 for(auto familyToKill = setOfCommonGrp.second.begin()+1 ; familyToKill != setOfCommonGrp.second.end(); ++familyToKill)
944 newFams.erase( newFams.find(*familyToKill) );
948 // apply modifications in datastructure
949 for(auto famIdsSubstSession : famIdsToSubstitute)
951 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
953 DataArrayIdType *fams(nullptr);
956 fams=getFamilyFieldAtLevel(*it);
958 catch(INTERP_KERNEL::Exception& ) { }
961 MCAuto<DataArrayIdType> idsToModif(fams->findIdsEqualList(famIdsSubstSession.second.data(),famIdsSubstSession.second.data()+famIdsSubstSession.second.size()));
962 fams->setPartOfValuesSimple3(famIdsSubstSession.first,idsToModif->begin(),idsToModif->end(),0,1,1);
970 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
972 void MEDFileMesh::checkOrphanFamilyZero() const
974 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
976 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
978 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
979 throw INTERP_KERNEL::Exception(oss.str().c_str());
985 * Renames a group in \a this mesh.
986 * \param [in] oldName - a current name of the group to rename.
987 * \param [in] newName - a new group name.
988 * \throw If no group named \a oldName exists in \a this mesh.
989 * \throw If a group named \a newName already exists.
991 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
993 std::string oname(oldName);
994 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
995 std::vector<std::string> grps=getGroupsNames();
996 if(it==_groups.end())
998 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
999 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1000 throw INTERP_KERNEL::Exception(oss.str().c_str());
1002 std::string nname(newName);
1003 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
1004 if(it2!=_groups.end())
1006 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
1007 throw INTERP_KERNEL::Exception(oss.str().c_str());
1009 std::vector<std::string> cpy=(*it).second;
1011 _groups[newName]=cpy;
1015 * Changes an id of a family in \a this mesh.
1016 * This method calls changeFamilyIdArr().
1017 * \param [in] oldId - a current id of the family.
1018 * \param [in] newId - a new family id.
1020 void MEDFileMesh::changeFamilyId(mcIdType oldId, mcIdType newId)
1022 changeFamilyIdArr(oldId,newId);
1023 std::map<std::string,mcIdType> fam2;
1024 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1026 if((*it).second==oldId)
1027 fam2[(*it).first]=newId;
1029 fam2[(*it).first]=(*it).second;
1035 * Renames a family in \a this mesh.
1036 * \param [in] oldName - a current name of the family to rename.
1037 * \param [in] newName - a new family name.
1038 * \throw If no family named \a oldName exists in \a this mesh.
1039 * \throw If a family named \a newName already exists.
1041 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
1043 std::string oname(oldName);
1044 std::map<std::string, mcIdType >::iterator it=_families.find(oname);
1045 std::vector<std::string> fams=getFamiliesNames();
1046 if(it==_families.end())
1048 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
1049 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1050 throw INTERP_KERNEL::Exception(oss.str().c_str());
1052 std::string nname(newName);
1053 std::map<std::string, mcIdType >::iterator it2=_families.find(nname);
1054 if(it2!=_families.end())
1056 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
1057 throw INTERP_KERNEL::Exception(oss.str().c_str());
1059 mcIdType cpy=(*it).second;
1060 _families.erase(it);
1061 _families[newName]=cpy;
1062 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
1064 std::vector<std::string>& v=(*it3).second;
1065 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
1072 * Checks if \a this and another mesh contains the same families.
1073 * \param [in] other - the mesh to compare with \a this one.
1074 * \param [in,out] what - an unused parameter.
1075 * \return bool - \c true if number of families and their ids are the same in the two
1076 * meshes. Families with the id == \c 0 are not considered.
1078 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
1080 if(_families==other->_families)
1082 std::map<std::string,mcIdType> fam0;
1083 std::map<std::string,mcIdType> fam1;
1084 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1086 fam0[(*it).first]=(*it).second;
1087 for(std::map<std::string,mcIdType>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
1089 fam1[(*it).first]=(*it).second;
1094 * Checks if \a this and another mesh contains the same groups.
1095 * \param [in] other - the mesh to compare with \a this one.
1096 * \param [in,out] what - a string describing a difference of groups of the two meshes
1097 * in case if this method returns \c false.
1098 * \return bool - \c true if number of groups and families constituting them are the
1099 * same in the two meshes.
1101 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
1103 if(_groups==other->_groups)
1106 std::size_t sz=_groups.size();
1107 if(sz!=other->_groups.size())
1109 what="Groups differ because not same number !\n";
1114 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
1115 for(std::size_t i=0;i<sz && ret;i++,it1++)
1117 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
1118 if(it2!=other->_groups.end())
1120 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
1121 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1127 what="A group in first mesh exists not in other !\n";
1133 std::ostringstream oss; oss << "Groups description differs :\n";
1134 oss << "First group description :\n";
1135 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1137 oss << " Group \"" << (*it).first << "\" on following families :\n";
1138 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1139 oss << " \"" << *it2 << "\n";
1141 oss << "Second group description :\n";
1142 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1144 oss << " Group \"" << (*it).first << "\" on following families :\n";
1145 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1146 oss << " \"" << *it2 << "\n";
1154 * Checks if a group with a given name exists in \a this mesh.
1155 * \param [in] groupName - the group name.
1156 * \return bool - \c true the group \a groupName exists in \a this mesh.
1158 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1160 std::string grpName(groupName);
1161 return _groups.find(grpName)!=_groups.end();
1165 * Checks if a family with a given id exists in \a this mesh.
1166 * \param [in] famId - the family id.
1167 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1169 bool MEDFileMesh::existsFamily(mcIdType famId) const
1171 for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1172 if((*it2).second==famId)
1178 * Checks if a family with a given name exists in \a this mesh.
1179 * \param [in] familyName - the family name.
1180 * \return bool - \c true the family \a familyName exists in \a this mesh.
1182 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1184 std::string fname(familyName);
1185 return _families.find(fname)!=_families.end();
1189 * Sets an id of a family.
1190 * \param [in] familyName - the family name.
1191 * \param [in] id - a new id of the family.
1193 void MEDFileMesh::setFamilyId(const std::string& familyName, mcIdType id)
1195 std::string fname(familyName);
1196 _families[fname]=id;
1199 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, mcIdType id)
1201 std::string fname(familyName);
1202 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1203 if((*it).second==id)
1205 if((*it).first!=familyName)
1207 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1208 throw INTERP_KERNEL::Exception(oss.str().c_str());
1211 _families[fname]=id;
1215 * Adds a family to \a this mesh.
1216 * \param [in] familyName - a name of the family.
1217 * \param [in] famId - an id of the family.
1218 * \throw If a family with the same name or id already exists in \a this mesh.
1220 void MEDFileMesh::addFamily(const std::string& familyName, mcIdType famId)
1222 std::string fname(familyName);
1223 std::map<std::string,mcIdType>::const_iterator it=_families.find(fname);
1224 if(it==_families.end())
1226 for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1227 if((*it2).second==famId)
1229 std::ostringstream oss;
1230 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1231 throw INTERP_KERNEL::Exception(oss.str().c_str());
1233 _families[fname]=famId;
1237 if((*it).second!=famId)
1239 std::ostringstream oss;
1240 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1241 throw INTERP_KERNEL::Exception(oss.str().c_str());
1247 * Creates a group including all mesh entities of given dimension.
1248 * \warning This method does \b not guarantee that the created group includes mesh
1249 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1250 * present in family fields of different dimensions. To assure this, call
1251 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1252 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1254 * \param [in] groupName - a name of the new group.
1255 * \throw If a group named \a groupName already exists.
1256 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1257 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1259 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1261 std::string grpName(groupName);
1262 std::vector<int> levs=getNonEmptyLevelsExt();
1263 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1265 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1266 oss << "Available relative ext levels are : ";
1267 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1268 throw INTERP_KERNEL::Exception(oss.str().c_str());
1270 if(existsGroup(groupName))
1272 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1273 oss << "Already existing groups are : ";
1274 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1275 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1276 throw INTERP_KERNEL::Exception(oss.str().c_str());
1278 const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1280 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1281 MCAuto<DataArrayIdType> famIds=fieldFamIds->getDifferentValues();
1282 std::vector<std::string> familiesOnWholeGroup;
1283 for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
1286 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1288 _groups[grpName]=familiesOnWholeGroup;
1292 * Ensures that given family ids do not present in family fields of dimensions different
1293 * than given ones. If a family id is present in the family fields of dimensions different
1294 * than the given ones, a new family is created and the whole data is updated accordingly.
1295 * \param [in] famIds - a sequence of family ids to check.
1296 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1297 * famIds should exclusively belong.
1298 * \return bool - \c true if no modification is done in \a this mesh by this method.
1300 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<mcIdType>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1302 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1303 std::vector<int> levs=getNonEmptyLevelsExt();
1304 std::set<int> levs2(levs.begin(),levs.end());
1305 std::vector<int> levsToTest;
1306 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1307 std::set<mcIdType> famIds2(famIds.begin(),famIds.end());
1309 mcIdType maxFamId=1;
1310 if(!_families.empty())
1311 maxFamId=getMaxFamilyId()+1;
1312 std::vector<std::string> allFams=getFamiliesNames();
1313 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1315 const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(*it);
1318 MCAuto<DataArrayIdType> famIds3=fieldFamIds->getDifferentValues();
1319 std::vector<mcIdType> tmp;
1320 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<mcIdType> >(tmp));
1321 for(std::vector<mcIdType>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1324 std::string famName=getFamilyNameGivenId(*it2);
1325 std::ostringstream oss; oss << "Family_" << maxFamId;
1326 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1327 addFamilyOnAllGroupsHaving(famName,zeName);
1328 _families[zeName]=maxFamId;
1329 (const_cast<DataArrayIdType *>(fieldFamIds))->changeValue(*it2,maxFamId);
1338 * Adds a family to a given group in \a this mesh. If the group with a given name does
1339 * not exist, it is created.
1340 * \param [in] grpName - the name of the group to add the family in.
1341 * \param [in] famName - the name of the family to add to the group named \a grpName.
1342 * \throw If \a grpName or \a famName is an empty string.
1343 * \throw If no family named \a famName is present in \a this mesh.
1345 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1347 std::string grpn(grpName);
1348 std::string famn(famName);
1349 if(grpn.empty() || famn.empty())
1350 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1351 std::vector<std::string> fams=getFamiliesNames();
1352 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1354 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1355 oss << "Create this family or choose an existing one ! Existing fams are : ";
1356 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1357 throw INTERP_KERNEL::Exception(oss.str().c_str());
1359 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1360 if(it==_groups.end())
1362 _groups[grpn].push_back(famn);
1366 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1367 if(it2==(*it).second.end())
1368 (*it).second.push_back(famn);
1373 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1374 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1375 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1377 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1379 std::string famNameCpp(famName);
1380 std::string otherCpp(otherFamName);
1381 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1383 std::vector<std::string>& v=(*it).second;
1384 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1386 v.push_back(otherCpp);
1391 void MEDFileMesh::checkNoGroupClash(const DataArrayIdType *famArr, const std::string& grpName) const
1393 std::vector<std::string> grpsNames(getGroupsNames());
1394 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
1396 std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(grpName));
1397 if(famArr->presenceOfValue(famIds))
1399 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
1400 throw INTERP_KERNEL::Exception(oss.str().c_str());
1405 * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
1406 * \param [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed)
1408 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayIdType *ids, DataArrayIdType *famArr)
1411 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1412 std::string grpName(ids->getName());
1414 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1415 ids->checkStrictlyMonotonic(true);
1416 checkNoGroupClash(famArr,grpName);
1417 MCAuto<DataArrayIdType> famArrTmp; famArrTmp.takeRef(famArr);
1418 std::list< MCAuto<DataArrayIdType> > allFamIds(getAllNonNullFamilyIds());
1419 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1420 MCAuto<DataArrayIdType> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1421 MCAuto<DataArrayIdType> diffFamIds=famIds->getDifferentValues();
1422 std::vector<mcIdType> familyIds;
1423 std::vector< MCAuto<DataArrayIdType> > idsPerfamiliyIds;
1424 mcIdType maxVal=getTheMaxAbsFamilyId()+1;
1425 std::map<std::string,mcIdType> families(_families);
1426 std::map<std::string, std::vector<std::string> > groups(_groups);
1427 std::vector<std::string> fams;
1428 bool created(false);
1429 for(const mcIdType *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1431 MCAuto<DataArrayIdType> ids2Tmp=famIds->findIdsEqual(*famId);
1432 MCAuto<DataArrayIdType> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1433 MCAuto<DataArrayIdType> ids1=famArr->findIdsEqual(*famId);
1434 MCAuto<DataArrayIdType> ret0(ids1->buildSubstractionOptimized(ids2));
1437 bool isFamPresent=false;
1438 for(std::list< MCAuto<DataArrayIdType> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1439 isFamPresent=(*itl)->presenceOfValue(*famId);
1440 if(!isFamPresent && *famId!=0)
1441 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1444 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1445 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1446 fams.push_back(locFamName);
1447 if(existsFamily(*famId))
1449 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1450 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1453 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1457 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1458 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1459 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1460 if(existsFamily(*famId))
1462 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1463 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1468 for(std::size_t i=0;i<familyIds.size();i++)
1470 DataArrayIdType *da=idsPerfamiliyIds[i];
1471 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1474 std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
1475 if(itt!=groups.end())
1477 std::vector<std::string>& famsOnGrp((*itt).second);
1478 famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
1481 groups[grpName]=fams;
1485 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1487 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1490 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1492 std::string fam(familyNameToChange);
1493 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1495 std::vector<std::string>& fams((*it).second);
1496 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1500 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1506 * Returns a name of the family having a given id or, if no such a family exists, creates
1507 * a new uniquely named family and returns its name.
1508 * \param [in] id - the id of the family whose name is required.
1509 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1510 * \return std::string - the name of the existing or the created family.
1511 * \throw If it is not possible to create a unique family name.
1513 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(mcIdType id, bool& created)
1515 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1519 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1520 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1521 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1522 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1524 * This method will throws an exception if it is not possible to create a unique family name.
1526 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,mcIdType>& families, mcIdType id, bool& created)
1528 std::vector<std::string> famAlreadyExisting(families.size());
1530 for(std::map<std::string,mcIdType>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1532 if((*it).second!=id)
1534 famAlreadyExisting[ii]=(*it).first;
1543 std::ostringstream oss; oss << "Family_" << id;
1544 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1550 * Sets names and ids of all families in \a this mesh.
1551 * \param [in] info - a map of a family name to a family id.
1553 void MEDFileMesh::setFamilyInfo(const std::map<std::string,mcIdType>& info)
1559 * Sets names of all groups and families constituting them in \a this mesh.
1560 * \param [in] info - a map of a group name to a vector of names of families
1561 * constituting the group.
1563 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1569 * Returns an id of the family having a given name.
1570 * \param [in] name - the name of the family of interest.
1571 * \return mcIdType - the id of the family of interest.
1572 * \throw If no family with such a \a name exists.
1574 mcIdType MEDFileMesh::getFamilyId(const std::string& name) const
1576 std::map<std::string, mcIdType>::const_iterator it=_families.find(name);
1577 if(it==_families.end())
1579 std::vector<std::string> fams(getFamiliesNames());
1580 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1581 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1582 throw INTERP_KERNEL::Exception(oss.str().c_str());
1584 return (*it).second;
1588 * Returns ids of the families having given names.
1589 * \param [in] fams - a sequence of the names of families of interest.
1590 * \return std::vector<mcIdType> - a sequence of the ids of families of interest.
1591 * \throw If \a fams contains a name of an inexistent family.
1593 std::vector<mcIdType> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1595 std::vector<mcIdType> ret(fams.size());
1597 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1599 std::map<std::string, mcIdType>::const_iterator it2=_families.find(*it);
1600 if(it2==_families.end())
1602 std::vector<std::string> fams2=getFamiliesNames();
1603 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1604 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1605 throw INTERP_KERNEL::Exception(oss.str().c_str());
1607 ret[i]=(*it2).second;
1613 * Returns a maximal abs(id) of families in \a this mesh.
1614 * \return mcIdType - the maximal norm of family id.
1615 * \throw If there are no families in \a this mesh.
1617 mcIdType MEDFileMesh::getMaxAbsFamilyId() const
1619 if(_families.empty())
1620 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1621 mcIdType ret=-std::numeric_limits<mcIdType>::max();
1622 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1624 ret=std::max(std::abs((*it).second),ret);
1630 * Returns a maximal id of families in \a this mesh.
1631 * \return mcIdType - the maximal family id.
1632 * \throw If there are no families in \a this mesh.
1634 mcIdType MEDFileMesh::getMaxFamilyId() const
1636 if(_families.empty())
1637 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1638 mcIdType ret=-std::numeric_limits<mcIdType>::max();
1639 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1641 ret=std::max((*it).second,ret);
1647 * Returns a minimal id of families in \a this mesh.
1648 * \return mcIdType - the minimal family id.
1649 * \throw If there are no families in \a this mesh.
1651 mcIdType MEDFileMesh::getMinFamilyId() const
1653 if(_families.empty())
1654 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1655 mcIdType ret=std::numeric_limits<mcIdType>::max();
1656 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1658 ret=std::min((*it).second,ret);
1664 * Returns a maximal id of families in \a this mesh. Not only named families are
1665 * considered but all family fields as well.
1666 * \return mcIdType - the maximal family id.
1668 mcIdType MEDFileMesh::getTheMaxAbsFamilyId() const
1670 mcIdType m1=-std::numeric_limits<mcIdType>::max();
1671 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1672 m1=std::max(std::abs((*it).second),m1);
1673 mcIdType m2=getMaxAbsFamilyIdInArrays();
1674 return std::max(m1,m2);
1678 * Returns a maximal id of families in \a this mesh. Not only named families are
1679 * considered but all family fields as well.
1680 * \return mcIdType - the maximal family id.
1682 mcIdType MEDFileMesh::getTheMaxFamilyId() const
1684 mcIdType m1=-std::numeric_limits<mcIdType>::max();
1685 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1686 m1=std::max((*it).second,m1);
1687 mcIdType m2=getMaxFamilyIdInArrays();
1688 return std::max(m1,m2);
1692 * Returns a minimal id of families in \a this mesh. Not only named families are
1693 * considered but all family fields as well.
1694 * \return mcIdType - the minimal family id.
1696 mcIdType MEDFileMesh::getTheMinFamilyId() const
1698 mcIdType m1=std::numeric_limits<mcIdType>::max();
1699 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1700 m1=std::min((*it).second,m1);
1701 mcIdType m2=getMinFamilyIdInArrays();
1702 return std::min(m1,m2);
1706 * This method only considers the maps. The contain of family array is ignored here.
1708 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1710 DataArrayIdType *MEDFileMesh::getAllFamiliesIdsReferenced() const
1712 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
1713 std::set<mcIdType> v;
1714 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1715 v.insert((*it).second);
1716 ret->alloc((mcIdType)v.size(),1);
1717 std::copy(v.begin(),v.end(),ret->getPointer());
1722 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1724 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1726 DataArrayIdType *MEDFileMesh::computeAllFamilyIdsInUse() const
1728 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1729 MCAuto<DataArrayIdType> ret;
1730 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1732 const DataArrayIdType *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1733 MCAuto<DataArrayIdType> dv=arr->getDifferentValues();
1734 if((DataArrayIdType *) ret)
1735 ret=dv->buildUnion(ret);
1743 * true is returned if no modification has been needed. false if family
1744 * renumbering has been needed.
1746 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1748 std::vector<int> levs=getNonEmptyLevelsExt();
1749 std::set<mcIdType> allFamIds;
1750 mcIdType maxId=getMaxFamilyId()+1;
1751 std::map<int,std::vector<mcIdType> > famIdsToRenum;
1752 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1754 const DataArrayIdType *fam=getFamilyFieldAtLevel(*it);
1757 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1758 std::set<mcIdType> r2;
1759 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1761 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1762 std::set<mcIdType> r3;
1763 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1766 if(famIdsToRenum.empty())
1768 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1769 for(std::map<int,std::vector<mcIdType> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1771 DataArrayIdType *fam=const_cast<DataArrayIdType *>(getFamilyFieldAtLevel((*it2).first));
1772 mcIdType *famIdsToChange=fam->getPointer();
1773 std::map<mcIdType,mcIdType> ren;
1774 for(std::vector<mcIdType>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1776 if(allIds->presenceOfValue(*it3))
1778 std::string famName=getFamilyNameGivenId(*it3);
1779 std::vector<std::string> grps=getGroupsOnFamily(famName);
1782 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1783 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1784 addFamilyOnGrp((*it4),newFam);
1787 MCAuto<DataArrayIdType> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1788 for(const mcIdType *id=ids->begin();id!=ids->end();id++)
1789 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1795 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1796 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1797 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1798 * This method will throw an exception if a same family id is detected in different level.
1799 * \warning This policy is the opposite of those in MED file documentation ...
1801 void MEDFileMesh::normalizeFamIdsTrio()
1803 ensureDifferentFamIdsPerLevel();
1804 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1805 std::vector<int> levs=getNonEmptyLevelsExt();
1806 std::set<int> levsS(levs.begin(),levs.end());
1807 std::set<std::string> famsFetched;
1808 std::map<std::string,mcIdType> families;
1809 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1812 const DataArrayIdType *fam=getFamilyFieldAtLevel(0);
1816 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1817 std::map<mcIdType,mcIdType> ren;
1818 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
1820 mcIdType nbOfTuples=fam->getNumberOfTuples();
1821 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1822 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1824 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1826 if(allIds->presenceOfValue(*it))
1828 std::string famName=getFamilyNameGivenId(*it);
1829 families[famName]=ren[*it];
1830 famsFetched.insert(famName);
1835 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1838 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
1842 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1843 std::map<mcIdType,mcIdType> ren;
1844 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
1846 mcIdType nbOfTuples=fam->getNumberOfTuples();
1847 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1848 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1850 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1852 if(allIds->presenceOfValue(*it))
1854 std::string famName=getFamilyNameGivenId(*it);
1855 families[famName]=ren[*it];
1856 famsFetched.insert(famName);
1861 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1863 DataArrayIdType *fam=const_cast<DataArrayIdType*>(getFamilyFieldAtLevel(*it2));
1866 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1867 fam->fillWithZero();
1868 for(const mcIdType *it3=tmp->begin();it3!=tmp->end();it3++)
1869 if(allIds->presenceOfValue(*it3))
1871 std::string famName=getFamilyNameGivenId(*it3);
1872 families[famName]=0;
1873 famsFetched.insert(famName);
1878 std::vector<std::string> allFams=getFamiliesNames();
1879 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1880 std::set<std::string> unFetchedIds;
1881 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1882 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1883 families[*it4]=_families[*it4];
1888 * This method normalizes fam id with the following policy.
1889 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1890 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1891 * This method will throw an exception if a same family id is detected in different level.
1893 void MEDFileMesh::normalizeFamIdsMEDFile()
1895 ensureDifferentFamIdsPerLevel();
1896 MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
1897 std::vector<int> levs=getNonEmptyLevelsExt();
1898 std::set<int> levsS(levs.begin(),levs.end());
1899 std::set<std::string> famsFetched;
1900 std::map<std::string,mcIdType> families;
1902 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1905 const DataArrayIdType *fam=getFamilyFieldAtLevel(1);
1908 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1909 std::map<mcIdType,mcIdType> ren;
1910 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
1912 mcIdType nbOfTuples=fam->getNumberOfTuples();
1913 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1914 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1916 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1918 if(allIds->presenceOfValue(*it))
1920 std::string famName=getFamilyNameGivenId(*it);
1921 families[famName]=ren[*it];
1922 famsFetched.insert(famName);
1928 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1930 const DataArrayIdType *fam=getFamilyFieldAtLevel(*it2);
1933 MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
1934 std::map<mcIdType,mcIdType> ren;
1935 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
1937 mcIdType nbOfTuples=fam->getNumberOfTuples();
1938 mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
1939 for(mcIdType *w=start;w!=start+nbOfTuples;w++)
1941 for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
1943 if(allIds->presenceOfValue(*it))
1945 std::string famName=getFamilyNameGivenId(*it);
1946 families[famName]=ren[*it];
1947 famsFetched.insert(famName);
1953 std::vector<std::string> allFams=getFamiliesNames();
1954 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1955 std::set<std::string> unFetchedIds;
1956 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1957 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1958 families[*it4]=_families[*it4];
1963 * Returns a name of the family by its id. If there are several families having the given
1964 * id, the name first in lexical order is returned.
1965 * \param [in] id - the id of the family whose name is required.
1966 * \return std::string - the name of the found family.
1967 * \throw If no family with the given \a id exists.
1969 std::string MEDFileMesh::getFamilyNameGivenId(mcIdType id) const
1971 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
1972 if((*it).second==id)
1974 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1975 throw INTERP_KERNEL::Exception(oss.str().c_str());
1979 * Returns a string describing \a this mesh. This description includes the mesh name and
1980 * the mesh description string.
1981 * \return std::string - the mesh information string.
1983 std::string MEDFileMesh::simpleRepr() const
1985 std::ostringstream oss;
1986 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1987 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1988 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1993 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1994 * an empty one is created.
1996 DataArrayIdType *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1998 DataArrayIdType *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
2001 MCAuto<DataArrayIdType> arr(DataArrayIdType::New());
2002 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
2003 arr->fillWithZero();
2004 setFamilyFieldArr(meshDimRelToMaxExt,arr);
2005 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
2009 * Returns ids of mesh entities contained in a given group of a given dimension.
2010 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2012 * \param [in] grp - the name of the group of interest.
2013 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2014 * returned instead of ids.
2015 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2016 * numbers, if available and required, of mesh entities of the group. The caller
2017 * is to delete this array using decrRef() as it is no more needed.
2018 * \throw If the name of a nonexistent group is specified.
2019 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2021 DataArrayIdType *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2023 std::vector<std::string> tmp(1);
2025 DataArrayIdType *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
2031 * Returns ids of mesh entities contained in given groups of a given dimension.
2032 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2034 * \param [in] grps - the names of the groups of interest.
2035 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2036 * returned instead of ids.
2037 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2038 * numbers, if available and required, of mesh entities of the groups. The caller
2039 * is to delete this array using decrRef() as it is no more needed.
2040 * \throw If the name of a nonexistent group is present in \a grps.
2041 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2043 DataArrayIdType *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2045 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2046 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
2050 * Returns ids of mesh entities contained in a given family of a given dimension.
2051 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2053 * \param [in] fam - the name of the family of interest.
2054 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2055 * returned instead of ids.
2056 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2057 * numbers, if available and required, of mesh entities of the family. The caller
2058 * is to delete this array using decrRef() as it is no more needed.
2059 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2061 DataArrayIdType *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2063 std::vector<std::string> tmp(1);
2065 DataArrayIdType *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
2071 * Returns ids of nodes contained in a given group.
2072 * \param [in] grp - the name of the group of interest.
2073 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2074 * returned instead of ids.
2075 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2076 * numbers, if available and required, of nodes of the group. The caller
2077 * is to delete this array using decrRef() as it is no more needed.
2078 * \throw If the name of a nonexistent group is specified.
2079 * \throw If the family field is missing for nodes.
2081 DataArrayIdType *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
2083 std::vector<std::string> tmp(1);
2085 DataArrayIdType *ret=getNodeGroupsArr(tmp,renum);
2091 * Returns ids of nodes contained in given groups.
2092 * \param [in] grps - the names of the groups of interest.
2093 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2094 * returned instead of ids.
2095 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2096 * numbers, if available and required, of nodes of the groups. The caller
2097 * is to delete this array using decrRef() as it is no more needed.
2098 * \throw If the name of a nonexistent group is present in \a grps.
2099 * \throw If the family field is missing for nodes.
2101 DataArrayIdType *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
2103 return getGroupsArr(1,grps,renum);
2107 * Returns ids of nodes contained in a given family.
2108 * \param [in] fam - the name of the family of interest.
2109 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2110 * returned instead of ids.
2111 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2112 * numbers, if available and required, of nodes of the family. The caller
2113 * is to delete this array using decrRef() as it is no more needed.
2114 * \throw If the name of a nonexistent family is specified.
2115 * \throw If the family field is missing for nodes.
2117 DataArrayIdType *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
2119 std::vector<std::string> tmp(1);
2121 DataArrayIdType *ret=getNodeFamiliesArr(tmp,renum);
2127 * Returns ids of nodes contained in given families.
2128 * \param [in] fams - the names of the families of interest.
2129 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
2130 * returned instead of ids.
2131 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
2132 * numbers, if available and required, of nodes of the families. The caller
2133 * is to delete this array using decrRef() as it is no more needed.
2134 * \throw If the family field is missing for nodes.
2136 DataArrayIdType *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2138 return getFamiliesArr(1,fams,renum);
2142 * Adds groups of given dimension and creates corresponding families and family fields
2143 * given ids of mesh entities of each group.
2144 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2145 * \param [in] grps - a sequence of arrays of ids each describing a group.
2146 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2148 * \throw If names of some groups in \a grps are equal.
2149 * \throw If \a grps includes a group with an empty name.
2150 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2151 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2153 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayIdType *>& grps, bool renum)
2157 std::set<std::string> grpsName;
2158 std::vector<std::string> grpsName2(grps.size());
2161 for(std::vector<const DataArrayIdType *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2163 grpsName.insert((*it)->getName());
2164 grpsName2[i]=(*it)->getName();
2166 if(grpsName.size()!=grps.size())
2167 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2168 if(grpsName.find(std::string(""))!=grpsName.end())
2169 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2170 mcIdType sz=getSizeAtLevel(meshDimRelToMaxExt);
2171 MCAuto<DataArrayIdType> fam;
2172 std::vector< std::vector<mcIdType> > fidsOfGroups;
2175 fam=DataArrayIdType::MakePartition(grps,sz,fidsOfGroups);
2179 std::vector< MCAuto<DataArrayIdType> > grps2(grps.size());
2180 for(unsigned int ii=0;ii<grps.size();ii++)
2182 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2183 grps2[ii]->setName(grps[ii]->getName());
2185 std::vector<const DataArrayIdType *> grps3(grps2.begin(),grps2.end());
2186 fam=DataArrayIdType::MakePartition(grps3,sz,fidsOfGroups);
2189 if(!_families.empty())
2190 offset=getMaxAbsFamilyId()+1;
2191 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2192 MCAuto<DataArrayIdType> ids=fam->getDifferentValues();
2193 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2194 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2198 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2199 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2200 * For the moment, the two last input parameters are not taken into account.
2202 void MEDFileMesh::appendFamilyEntries(const DataArrayIdType *famIds, const std::vector< std::vector<mcIdType> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2204 std::map<mcIdType,std::string> famInv;
2205 for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
2207 std::ostringstream oss;
2208 oss << "Family_" << (*it);
2209 _families[oss.str()]=(*it);
2210 famInv[*it]=oss.str();
2213 for(std::vector< std::vector<mcIdType> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2215 for(std::vector<mcIdType>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2217 _groups[grpNames[i]].push_back(famInv[*it2]);
2222 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2224 std::vector<int> levs(getNonEmptyLevels());
2225 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2226 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2228 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2229 ret.insert(ret.end(),elts.begin(),elts.end());
2235 * \sa getAllDistributionOfTypes
2237 std::vector<mcIdType> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2239 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2240 return mLev->getDistributionOfTypes();
2243 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2245 loadLL(fid,mName,dt,it,mrs);
2246 loadJointsFromFile(fid);
2247 loadEquivalences(fid);
2250 void MEDFileMesh::TranslateFamilyIds(mcIdType offset, DataArrayIdType *famArr, std::vector< std::vector<mcIdType> >& famIdsPerGrp)
2252 famArr->applyLin(offset>0?1:-1,offset,0);
2253 for(std::vector< std::vector<mcIdType> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2256 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<mcIdType>());
2257 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind(std::plus<mcIdType>(),std::placeholders::_1,offset));
2262 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2263 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2264 * If this method fails to find such a name it will throw an exception.
2266 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2269 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2272 std::size_t len=nameTry.length();
2273 for(std::size_t ii=1;ii<len;ii++)
2275 std::string tmp=nameTry.substr(ii,len-ii);
2276 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2282 for(char i=1;i<30;i++)
2284 std::string tmp1(nameTry.at(0),i);
2286 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2292 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2294 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2296 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2299 mcIdType MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<mcIdType>& code, mcIdType strt)
2301 std::size_t nbOfChunks=code.size()/3;
2302 if(code.size()%3!=0)
2303 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2305 for(std::size_t i=0;i<nbOfChunks;i++)
2314 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2315 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2316 * If _name is not empty and that 'm' has the same name nothing is done.
2317 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2319 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2322 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2327 std::string name(m->getName());
2332 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2333 oss << name << "' ! Names must match !";
2334 throw INTERP_KERNEL::Exception(oss.str().c_str());
2338 if(_desc_name.empty())
2339 _desc_name=m->getDescription();
2342 std::string name(m->getDescription());
2345 if(_desc_name!=name)
2347 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2348 oss << name << "' ! Names must match !";
2349 throw INTERP_KERNEL::Exception(oss.str().c_str());
2355 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2357 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2358 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
2360 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2361 oss << " - Groups lying on this family : ";
2362 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2363 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2364 oss << std::endl << std::endl;
2369 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2370 * file. The mesh to load is specified by its name and numbers of a time step and an
2372 * \param [in] fileName - the name of MED file to read.
2373 * \param [in] mName - the name of the mesh to read.
2374 * \param [in] dt - the number of a time step.
2375 * \param [in] it - the number of an iteration.
2376 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2377 * mesh using decrRef() as it is no more needed.
2378 * \throw If the file is not readable.
2379 * \throw If there is no mesh with given attributes in the file.
2380 * \throw If the mesh in the file is not an unstructured one.
2382 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2384 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2385 return New(fid,mName,dt,it,mrs);
2388 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2390 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2394 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2395 * file. The first mesh in the file is loaded.
2396 * \param [in] fileName - the name of MED file to read.
2397 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2398 * mesh using decrRef() as it is no more needed.
2399 * \throw If the file is not readable.
2400 * \throw If there is no meshes in the file.
2401 * \throw If the mesh in the file is not an unstructured one.
2403 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2405 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2406 return New(fid,mrs);
2410 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2412 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2415 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2416 throw INTERP_KERNEL::Exception(oss.str().c_str());
2419 MEDCoupling::MEDCouplingMeshType meshType;
2421 MEDCoupling::MEDCouplingAxisType dummy3;
2422 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2423 return T::New(fid,ms.front(),dt,it,mrs);
2426 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2428 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2432 * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2433 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2435 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2438 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2439 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2440 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2441 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2443 m2D->setCoords(m3D->getCoords());
2444 ret->setMeshAtLevel(0,m3D);
2445 ret->setMeshAtLevel(-1,m2D);
2446 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<med_int>::max()-mem->get2DCellIdForExtrusion());
2451 * Returns an empty instance of MEDFileUMesh.
2452 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2453 * mesh using decrRef() as it is no more needed.
2455 MEDFileUMesh *MEDFileUMesh::New()
2457 return new MEDFileUMesh;
2461 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2462 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2463 * \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.
2464 * 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
2465 * at most the memory consumtion.
2467 * \param [in] fileName - the name of the file.
2468 * \param [in] mName - the name of the mesh to be read.
2469 * \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.
2470 * \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.
2471 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2472 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2473 * \param [in] mrs - the request for what to be loaded.
2474 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2476 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)
2478 MEDFileUtilities::CheckFileForRead(fileName);
2479 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2480 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2484 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2485 * This method is \b NOT wrapped into python.
2487 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)
2489 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2490 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2495 * This method is an helper to load only consecutive nodes chunk of data of MED file pointed by \a fileName.
2496 * Consecutive chunk is specified classicaly by start (included) stop (excluded) format with \a startNodeId and \a stopNodeId respectively.
2497 * This method returns 5 elements.
2499 * \param [in] fileName - Name of file nodes to be read of.
2500 * \param [in] mName - Name of the mesh inside file pointed be \a fileName nodes to be read of.
2501 * \param [in] dt - Time iteration inside file pointed be \a fileName nodes to be read of.
2502 * \param [in] it - Time order inside file pointed be \a fileName nodes to be read of.
2503 * \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.
2504 * \param [in] startNodeId - Start Node Id (included) of chunk of data to be read
2505 * \param [in] stopNodeId - Start Node Id (included) of chunk of data to be read
2506 * \param [out] coords - output coordinates of requested chunk (DataArrayDouble)
2507 * \param [out] partCoords - output PartDefinition object of chunk
2508 * \param [out] famCoords - output family id field of requested chunk (DataArrayIdType)
2509 * \param [out] numCoords - output num id field of requested chunk (DataArrayIdType)
2510 * \param [out] nameCoords - output names on nodes of requested chunk (DataArrayAsciiChar)
2512 * \sa MEDLoaderUMesh::LoadPartOf
2514 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,
2515 MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<DataArrayIdType>& famCoords, MCAuto<DataArrayIdType>& numCoords, MCAuto<DataArrayAsciiChar>& nameCoords)
2517 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2518 MEDFileUMeshL2::LoadPartCoords(fid,infosOnComp,mName,dt,it,startNodeId,stopNodeId,coords,partCoords,famCoords,numCoords,nameCoords);
2521 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2523 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2524 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2528 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2530 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2531 ret.push_back((const DataArrayDouble*)_coords);
2532 ret.push_back((const DataArrayIdType *)_fam_coords);
2533 ret.push_back((const DataArrayIdType *)_num_coords);
2534 ret.push_back((const DataArrayIdType *)_global_num_coords);
2535 ret.push_back((const DataArrayIdType *)_rev_num_coords);
2536 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2537 ret.push_back((const PartDefinition *)_part_coords);
2538 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2539 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2540 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2541 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2545 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2547 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2551 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2553 return new MEDFileUMesh;
2556 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2558 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2559 ret->deepCpyEquivalences(*this);
2560 if(_coords.isNotNull())
2561 ret->_coords=_coords->deepCopy();
2562 if(_fam_coords.isNotNull())
2563 ret->_fam_coords=_fam_coords->deepCopy();
2564 if(_num_coords.isNotNull())
2565 ret->_num_coords=_num_coords->deepCopy();
2566 if(_global_num_coords.isNotNull())
2567 ret->_global_num_coords=_global_num_coords->deepCopy();
2568 if(_rev_num_coords.isNotNull())
2569 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2570 if(_name_coords.isNotNull())
2571 ret->_name_coords=_name_coords->deepCopy();
2573 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2575 if((const MEDFileUMeshSplitL1 *)(*it))
2576 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2578 if((const PartDefinition*)_part_coords)
2579 ret->_part_coords=_part_coords->deepCopy();
2584 * Checks if \a this and another mesh are equal.
2585 * \param [in] other - the mesh to compare with.
2586 * \param [in] eps - a precision used to compare real values.
2587 * \param [in,out] what - the string returning description of unequal data.
2588 * \return bool - \c true if the meshes are equal, \c false, else.
2590 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2592 if(!MEDFileMesh::isEqual(other,eps,what))
2594 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2597 what="Mesh types differ ! This is unstructured and other is NOT !";
2600 clearNonDiscrAttributes();
2601 otherC->clearNonDiscrAttributes();
2602 const DataArrayDouble *coo1=_coords;
2603 const DataArrayDouble *coo2=otherC->_coords;
2604 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2606 what="Mismatch of coordinates ! One is defined and not other !";
2611 bool ret=coo1->isEqual(*coo2,eps);
2614 what="Coords differ !";
2619 const DataArrayIdType *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2620 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2622 what="Mismatch of families arr on nodes ! One is defined and not other !";
2627 bool ret=famc1->isEqual(*famc2);
2630 what="Families arr on node differ !";
2636 const DataArrayIdType *numc1(_num_coords),*numc2(otherC->_num_coords);
2637 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2639 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2644 bool ret=numc1->isEqual(*numc2);
2647 what="Numbering arr on node differ !";
2653 const DataArrayIdType *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2654 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2656 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2661 bool ret=gnumc1->isEqual(*gnumc2);
2664 what="Global numbering arr on node differ !";
2670 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2671 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2673 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2678 bool ret=namec1->isEqual(*namec2);
2681 what="Names arr on node differ !";
2686 if(_ms.size()!=otherC->_ms.size())
2688 what="Number of levels differs !";
2691 std::size_t sz=_ms.size();
2692 for(std::size_t i=0;i<sz;i++)
2694 const MEDFileUMeshSplitL1 *s1=_ms[i];
2695 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2696 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2698 what="Mismatch of presence of sub levels !";
2703 bool ret=s1->isEqual(s2,eps,what);
2708 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2711 if((!pd0 && pd1) || (pd0 && !pd1))
2713 what=std::string("node part def is defined only for one among this or other !");
2716 return pd0->isEqual(pd1,what);
2720 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2721 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2722 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2723 * \throw if internal family array is inconsistent
2724 * \sa checkSMESHConsistency()
2726 void MEDFileUMesh::checkConsistency() const
2728 if(!_coords || !_coords->isAllocated())
2731 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2733 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2734 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2735 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2739 mcIdType nbCoo = _coords->getNumberOfTuples();
2740 if (_fam_coords.isNotNull())
2741 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2742 if (_num_coords.isNotNull())
2744 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2746 mcIdType maxValue=_num_coords->getMaxValue(pos);
2747 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2748 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2750 if (_global_num_coords.isNotNull())
2752 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2754 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2755 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2756 if (_num_coords && !_num_coords->hasUniqueValues())
2757 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2759 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2760 // Now sub part check:
2761 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2762 it != _ms.end(); it++)
2763 (*it)->checkConsistency();
2768 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2769 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2770 * entities as it likes), or non overlapping between all sub-levels.
2771 * \throw if the condition above is not respected
2773 void MEDFileUMesh::checkSMESHConsistency() const
2776 // For all sub-levels, numbering is either always null or with void intersection:
2779 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2780 std::vector< const DataArrayIdType * > v;
2781 bool voidOrNot = ((*it)->_num == 0);
2782 for (it++; it != _ms.end(); it++)
2783 if( ((*it)->_num == 0) != voidOrNot )
2784 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2785 else if (!voidOrNot)
2786 v.push_back((*it)->_num);
2789 // don't forget the 1st one:
2790 v.push_back(_ms[0]->_num);
2791 MCAuto<DataArrayIdType> inter = DataArrayIdType::BuildIntersection(v);
2792 if (inter->getNumberOfTuples())
2793 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2799 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2800 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2802 void MEDFileUMesh::clearNodeAndCellNumbers()
2804 _num_coords.nullify();
2805 _rev_num_coords.nullify();
2806 _global_num_coords.nullify();
2807 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2809 (*it)->_num.nullify();
2810 (*it)->_rev_num.nullify();
2811 (*it)->_global_num.nullify();
2816 * Clears redundant attributes of incorporated data arrays.
2818 void MEDFileUMesh::clearNonDiscrAttributes() const
2820 MEDFileMesh::clearNonDiscrAttributes();
2821 if(_coords.isNotNull())
2822 _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2823 if(_fam_coords.isNotNull())
2824 _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2825 if(_num_coords.isNotNull())
2826 _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2827 if(_name_coords.isNotNull())
2828 _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
2829 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2831 if((*it).isNotNull())
2832 (*it)->clearNonDiscrAttributes();
2836 void MEDFileUMesh::setName(const std::string& name)
2838 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2839 if((*it).isNotNull())
2840 (*it)->setName(name);
2841 MEDFileMesh::setName(name);
2844 MEDFileUMesh::MEDFileUMesh()
2848 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2851 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2853 catch(INTERP_KERNEL::Exception& e)
2859 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2860 * See MEDFileUMesh::LoadPartOf for detailed description.
2864 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)
2866 MEDFileUMeshL2 loaderl2;
2867 MEDCoupling::MEDCouplingMeshType meshType;
2870 MEDCoupling::MEDCouplingAxisType dummy3;
2871 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2872 if(meshType!=UNSTRUCTURED)
2874 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2875 throw INTERP_KERNEL::Exception(oss.str().c_str());
2877 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2878 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2882 * \brief Write joints in a file
2884 void MEDFileMesh::writeJoints(med_idt fid) const
2886 if ( _joints.isNotNull() )
2887 _joints->writeLL(fid);
2891 * \brief Load joints in a file or use provided ones
2893 //================================================================================
2895 * \brief Load joints in a file or use provided ones
2896 * \param [in] fid - MED file descriptor
2897 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2898 * Usually this joints are those just read by another iteration
2899 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2901 //================================================================================
2903 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2905 if ( toUseInstedOfReading )
2906 setJoints( toUseInstedOfReading );
2908 _joints = MEDFileJoints::New( fid, _name );
2911 void MEDFileMesh::loadEquivalences(med_idt fid)
2913 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2915 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2918 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2920 const MEDFileEquivalences *equiv(other._equiv);
2922 _equiv=equiv->deepCopy(this);
2925 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2927 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2928 if(!thisEq && !otherEq)
2930 if(thisEq && otherEq)
2931 return thisEq->isEqual(otherEq,what);
2934 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2939 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2941 const MEDFileEquivalences *equiv(_equiv);
2944 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2945 _equiv->getRepr(oss);
2948 void MEDFileMesh::checkCartesian() const
2950 if(getAxisType()!=AX_CART)
2952 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()) << ").";
2953 oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
2954 oss << " - call setAxisType(AX_CART)" << std::endl;
2955 oss << " - call cartesianize()";
2956 throw INTERP_KERNEL::Exception(oss.str().c_str());
2961 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2963 int MEDFileMesh::getNumberOfJoints() const
2965 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2969 * \brief Return joints with all adjacent mesh domains
2971 MEDFileJoints * MEDFileMesh::getJoints() const
2973 return const_cast<MEDFileJoints*>(& (*_joints));
2976 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2978 if ( joints != _joints )
2987 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2989 * \sa loadPartUMeshFromFile
2991 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2993 MEDFileUMeshL2 loaderl2;
2994 MEDCoupling::MEDCouplingMeshType meshType;
2997 MEDCoupling::MEDCouplingAxisType axType;
2998 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2999 setAxisType(axType);
3000 if(meshType!=UNSTRUCTURED)
3002 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
3003 throw INTERP_KERNEL::Exception(oss.str().c_str());
3005 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
3006 dispatchLoadedPart(fid,loaderl2,mName,mrs);
3007 // Structure element part...
3008 med_int nModels(-1);
3010 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
3011 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
3015 _elt_str.resize(nModels);
3016 for(int i=0;i<nModels;i++)
3017 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
3020 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
3022 int lev=loaderl2.getNumberOfLevels();
3024 for(int i=0;i<lev;i++)
3026 if(!loaderl2.emptyLev(i))
3027 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
3031 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
3033 setName(loaderl2.getName());
3034 setDescription(loaderl2.getDescription());
3035 setUnivName(loaderl2.getUnivName());
3036 setIteration(loaderl2.getIteration());
3037 setOrder(loaderl2.getOrder());
3038 setTimeValue(loaderl2.getTime());
3039 setTimeUnit(loaderl2.getTimeUnit());
3040 _coords=loaderl2.getCoords();
3041 if(!mrs || mrs->isNodeFamilyFieldReading())
3042 _fam_coords=loaderl2.getCoordsFamily();
3043 if(!mrs || mrs->isNodeNumFieldReading())
3044 _num_coords=loaderl2.getCoordsNum();
3045 if(!mrs || mrs->isNodeNameFieldReading())
3046 _name_coords=loaderl2.getCoordsName();
3047 if(!mrs || mrs->isGlobalNodeNumFieldReading())
3048 _global_num_coords=loaderl2.getCoordsGlobalNum();
3049 _part_coords=loaderl2.getPartDefOfCoo();
3052 MEDFileUMesh::~MEDFileUMesh()
3056 void MEDFileUMesh::writeMeshLL(med_idt fid) const
3058 const DataArrayDouble *coo=_coords;
3059 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
3060 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
3061 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
3062 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
3063 int spaceDim=(int)(coo?coo->getNumberOfComponents():0);
3066 mdim=getMeshDimension();
3067 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3068 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
3069 for(int i=0;i<spaceDim;i++)
3071 std::string info=coo->getInfoOnComponent(i);
3073 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
3074 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
3075 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
3077 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
3079 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
3080 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
3081 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
3082 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3083 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3084 (*it)->write(fid,meshName,mdim);
3085 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
3089 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
3090 * \return std::vector<int> - a sequence of the relative dimensions.
3092 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
3094 std::vector<int> ret;
3096 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3097 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3104 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
3105 * \return std::vector<int> - a sequence of the relative dimensions.
3107 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
3109 std::vector<int> ret0=getNonEmptyLevels();
3110 if((const DataArrayDouble *) _coords)
3112 std::vector<int> ret(ret0.size()+1);
3114 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3120 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
3122 std::vector<int> ret;
3123 const DataArrayIdType *famCoo(_fam_coords);
3127 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3129 const MEDFileUMeshSplitL1 *cur(*it);
3131 if(cur->getFamilyField())
3137 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
3139 std::vector<int> ret;
3140 if(_num_coords.isNotNull())
3143 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3145 const MEDFileUMeshSplitL1 *cur(*it);
3147 if(cur->getNumberField())
3153 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
3155 std::vector<int> ret;
3156 const DataArrayAsciiChar *nameCoo(_name_coords);
3160 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
3162 const MEDFileUMeshSplitL1 *cur(*it);
3164 if(cur->getNameField())
3171 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
3172 * To include nodes, call getFamsNonEmptyLevelsExt() method.
3173 * \param [in] fams - the name of the family of interest.
3174 * \return std::vector<int> - a sequence of the relative dimensions.
3176 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3178 std::vector<mcIdType> ret;
3179 std::vector<int> levs(getNonEmptyLevels());
3180 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3181 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3182 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3188 * Returns all relative mesh levels (including nodes) where given families are defined.
3189 * \param [in] fams - the names of the families of interest.
3190 * \return std::vector<int> - a sequence of the relative dimensions.
3192 std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3194 std::vector<mcIdType> ret0(getFamsNonEmptyLevels(fams));
3195 const DataArrayIdType *famCoords(_fam_coords);
3198 std::vector<mcIdType> famIds(getFamiliesIds(fams));
3199 if(famCoords->presenceOfValue(famIds))
3201 std::vector<mcIdType> ret(ret0.size()+1);
3203 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3210 mcIdType MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3212 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3213 if((const DataArrayIdType *)_fam_coords)
3215 mcIdType val=_fam_coords->getMaxValue(tmp);
3216 ret=std::max(ret,std::abs(val));
3218 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3220 if((const MEDFileUMeshSplitL1 *)(*it))
3222 const DataArrayIdType *da=(*it)->getFamilyField();
3225 mcIdType val=da->getMaxValue(tmp);
3226 ret=std::max(ret,std::abs(val));
3233 mcIdType MEDFileUMesh::getMaxFamilyIdInArrays() const
3235 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
3236 if((const DataArrayIdType *)_fam_coords)
3238 mcIdType val=_fam_coords->getMaxValue(tmp);
3239 ret=std::max(ret,val);
3241 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3243 if((const MEDFileUMeshSplitL1 *)(*it))
3245 const DataArrayIdType *da=(*it)->getFamilyField();
3248 mcIdType val=da->getMaxValue(tmp);
3249 ret=std::max(ret,val);
3256 mcIdType MEDFileUMesh::getMinFamilyIdInArrays() const
3258 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
3259 if((const DataArrayIdType *)_fam_coords)
3261 mcIdType val=_fam_coords->getMinValue(tmp);
3262 ret=std::min(ret,val);
3264 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3266 if((const MEDFileUMeshSplitL1 *)(*it))
3268 const DataArrayIdType *da=(*it)->getFamilyField();
3271 mcIdType val=da->getMinValue(tmp);
3272 ret=std::min(ret,val);
3280 * Returns the dimension on cells in \a this mesh.
3281 * \return int - the mesh dimension.
3282 * \throw If there are no cells in this mesh.
3284 int MEDFileUMesh::getMeshDimension() const
3287 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3288 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3289 return (*it)->getMeshDimension()+lev;
3290 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3294 * Returns the space dimension of \a this mesh that is equal to number of components in
3295 * the node coordinates array.
3296 * \return int - the space dimension of \a this mesh.
3297 * \throw If the node coordinates array is not available.
3299 int MEDFileUMesh::getSpaceDimension() const
3301 const DataArrayDouble *coo=_coords;
3303 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3304 return (int)coo->getNumberOfComponents();
3308 * Returns a string describing \a this mesh.
3309 * \return std::string - the mesh information string.
3311 std::string MEDFileUMesh::simpleRepr() const
3313 std::ostringstream oss;
3314 oss << MEDFileMesh::simpleRepr();
3315 const DataArrayDouble *coo=_coords;
3316 oss << "- The dimension of the space is ";
3317 static const char MSG1[]= "*** NO COORDS SET ***";
3318 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3320 oss << _coords->getNumberOfComponents() << std::endl;
3322 oss << MSG1 << std::endl;
3323 oss << "- Type of the mesh : UNSTRUCTURED\n";
3324 oss << "- Number of nodes : ";
3326 oss << _coords->getNumberOfTuples() << std::endl;
3328 oss << MSG1 << std::endl;
3329 std::size_t nbOfLev=_ms.size();
3330 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3331 for(std::size_t i=0;i<nbOfLev;i++)
3333 const MEDFileUMeshSplitL1 *lev=_ms[i];
3334 oss << " - Level #" << -((int) i) << " has dimension : ";
3337 oss << lev->getMeshDimension() << std::endl;
3338 lev->simpleRepr(oss);
3341 oss << MSG2 << std::endl;
3343 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3346 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3347 oss << "- Names of coordinates :" << std::endl;
3348 std::vector<std::string> vars=coo->getVarsOnComponent();
3349 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3350 oss << std::endl << "- Units of coordinates : " << std::endl;
3351 std::vector<std::string> units=coo->getUnitsOnComponent();
3352 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3354 oss << std::endl << std::endl;
3356 getEquivalencesRepr(oss);
3361 * Returns a full textual description of \a this mesh.
3362 * \return std::string - the string holding the mesh description.
3364 std::string MEDFileUMesh::advancedRepr() const
3366 return simpleRepr();
3370 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3371 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3372 * \return mcIdType - the number of entities.
3373 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3375 mcIdType MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3377 if(meshDimRelToMaxExt==1)
3379 if(!((const DataArrayDouble *)_coords))
3380 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3381 return _coords->getNumberOfTuples();
3383 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3387 * Returns the family field for mesh entities of a given dimension.
3388 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3389 * \return const DataArrayIdType * - the family field. It is an array of ids of families
3390 * each mesh entity belongs to. It can be \c NULL.
3392 const DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3394 if(meshDimRelToMaxExt==1)
3396 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3397 return l1->getFamilyField();
3400 DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3402 if(meshDimRelToMaxExt==1)
3404 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3405 return l1->getFamilyField();
3409 * Returns the optional numbers of mesh entities of a given dimension.
3410 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3411 * \return const DataArrayIdType * - the array of the entity numbers.
3412 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3414 const DataArrayIdType *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3416 if(meshDimRelToMaxExt==1)
3418 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3419 return l1->getNumberField();
3422 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3424 if(meshDimRelToMaxExt==1)
3425 return _name_coords;
3426 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3427 return l1->getNameField();
3430 MCAuto<DataArrayIdType> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
3432 if(meshDimRelToMaxExt!=1)
3433 throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
3434 return _global_num_coords;
3438 * 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).
3440 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3441 * \param [in] gt - The input geometric type for which the part definition is requested.
3442 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3444 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3446 if(meshDimRelToMaxExt==1)
3447 return _part_coords;
3448 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3449 return l1->getPartDef(gt);
3452 mcIdType MEDFileUMesh::getNumberOfNodes() const
3454 const DataArrayDouble *coo(_coords);
3456 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3457 return coo->getNumberOfTuples();
3460 mcIdType MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3462 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3463 return l1->getNumberOfCells();
3466 bool MEDFileUMesh::hasImplicitPart() const
3471 mcIdType MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3473 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3476 void MEDFileUMesh::releaseImplicitPartIfAny() const
3480 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3482 std::size_t sz(st.getNumberOfItems());
3483 for(std::size_t i=0;i<sz;i++)
3485 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3486 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3487 if(st[i].getPflName().empty())
3488 m->computeNodeIdsAlg(nodesFetched);
3491 const DataArrayIdType *arr(globs->getProfile(st[i].getPflName()));
3492 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3493 m2->computeNodeIdsAlg(nodesFetched);
3498 MEDFileMesh *MEDFileUMesh::cartesianize() const
3500 if(getAxisType()==AX_CART)
3503 return const_cast<MEDFileUMesh *>(this);
3507 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3508 const DataArrayDouble *coords(_coords);
3510 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3511 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3512 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3513 if((const MEDFileUMeshSplitL1 *)(*it))
3514 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3515 ret->_coords=coordsCart;
3516 ret->setAxisType(AX_CART);
3521 bool MEDFileUMesh::presenceOfStructureElements() const
3523 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3524 if((*it).isNotNull())
3529 void MEDFileUMesh::killStructureElements()
3535 * Returns the optional numbers of mesh entities of a given dimension transformed using
3536 * DataArrayIdType::invertArrayN2O2O2N().
3537 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3538 * \return const DataArrayIdType * - the array of the entity numbers transformed using
3539 * DataArrayIdType::invertArrayN2O2O2N().
3540 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3542 const DataArrayIdType *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3544 if(meshDimRelToMaxExt==1)
3546 if(_num_coords.isNull())
3547 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3548 return _rev_num_coords;
3550 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3551 return l1->getRevNumberField();
3555 * Returns a pointer to the node coordinates array of \a this mesh \b without
3556 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3558 DataArrayDouble *MEDFileUMesh::getCoords() const
3561 MCAuto<DataArrayDouble> tmp(_coords);
3562 if((DataArrayDouble *)tmp)
3570 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3571 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3573 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3574 * \param [in] grp - the name of the group whose mesh entities are included in the
3576 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3577 * according to the optional numbers of entities, if available.
3578 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3579 * delete this mesh using decrRef() as it is no more needed.
3580 * \throw If the name of a nonexistent group is specified.
3581 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3583 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3586 synchronizeTinyInfoOnLeaves();
3587 std::vector<std::string> tmp(1);
3589 return getGroups(meshDimRelToMaxExt,tmp,renum);
3593 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3594 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3596 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3597 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3599 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3600 * according to the optional numbers of entities, if available.
3601 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3602 * delete this mesh using decrRef() as it is no more needed.
3603 * \throw If a name of a nonexistent group is present in \a grps.
3604 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3606 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3609 synchronizeTinyInfoOnLeaves();
3610 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3611 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3612 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3613 zeRet->setName(grps[0]);
3614 return zeRet.retn();
3618 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3619 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3621 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3622 * \param [in] fam - the name of the family whose mesh entities are included in the
3624 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3625 * according to the optional numbers of entities, if available.
3626 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3627 * delete this mesh using decrRef() as it is no more needed.
3628 * \throw If a name of a nonexistent family is present in \a grps.
3629 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3631 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3634 synchronizeTinyInfoOnLeaves();
3635 std::vector<std::string> tmp(1);
3637 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3641 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3642 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3644 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3645 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3647 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3648 * according to the optional numbers of entities, if available.
3649 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3650 * delete this mesh using decrRef() as it is no more needed.
3651 * \throw If a name of a nonexistent family is present in \a fams.
3652 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3654 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3657 synchronizeTinyInfoOnLeaves();
3658 if(meshDimRelToMaxExt==1)
3660 MCAuto<DataArrayIdType> arr=getFamiliesArr(1,fams,renum);
3661 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3662 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3666 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3667 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3668 MCAuto<MEDCouplingUMesh> zeRet;
3670 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3672 zeRet=l1->getFamilyPart(0,0,renum);
3673 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3674 zeRet->setName(fams[0]);
3675 return zeRet.retn();
3679 * Returns ids of mesh entities contained in given families of a given dimension.
3680 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3682 * \param [in] fams - the names of the families of interest.
3683 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3684 * returned instead of ids.
3685 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
3686 * numbers, if available and required, of mesh entities of the families. The caller
3687 * is to delete this array using decrRef() as it is no more needed.
3688 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3690 DataArrayIdType *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3692 std::vector<mcIdType> famIds=getFamiliesIds(fams);
3693 if(meshDimRelToMaxExt==1)
3695 if((const DataArrayIdType *)_fam_coords)
3697 MCAuto<DataArrayIdType> da;
3699 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3701 da=_fam_coords->findIdsEqualList(0,0);
3703 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3708 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3710 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3712 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3714 return l1->getFamilyPartArr(0,0,renum);
3718 * Returns a MEDCouplingUMesh of a given relative dimension.
3719 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3720 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3721 * To build a valid MEDCouplingUMesh from the returned one in this case,
3722 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3723 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3724 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3725 * optional numbers of mesh entities.
3726 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3727 * delete using decrRef() as it is no more needed.
3728 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3730 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3733 synchronizeTinyInfoOnLeaves();
3734 if(meshDimRelToMaxExt==1)
3738 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3739 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3740 umesh->setCoords(cc);
3741 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3742 umesh->setName(getName());
3746 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3747 return l1->getWholeMesh(renum);
3750 std::vector<mcIdType> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3752 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3753 return l1->getDistributionOfTypes();
3757 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3758 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3759 * optional numbers of mesh entities.
3760 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3761 * delete using decrRef() as it is no more needed.
3762 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3764 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3766 return getMeshAtLevel(0,renum);
3770 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3771 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3772 * optional numbers of mesh entities.
3773 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3774 * delete using decrRef() as it is no more needed.
3775 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3777 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3779 return getMeshAtLevel(-1,renum);
3783 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3784 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3785 * optional numbers of mesh entities.
3786 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3787 * delete using decrRef() as it is no more needed.
3788 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3790 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3792 return getMeshAtLevel(-2,renum);
3796 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3797 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3798 * optional numbers of mesh entities.
3799 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3800 * delete using decrRef() as it is no more needed.
3801 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3803 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3805 return getMeshAtLevel(-3,renum);
3809 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3810 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3811 * When assignment is done the first one is done, which is not optimal in write mode for MED file.
3812 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3814 void MEDFileUMesh::forceComputationOfParts() const
3816 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3818 const MEDFileUMeshSplitL1 *elt(*it);
3820 elt->forceComputationOfParts();
3825 * This method returns a vector of mesh parts containing each exactly one geometric type.
3826 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3827 * This method is only for memory aware users.
3828 * The returned pointers are **NOT** new object pointer. No need to mange them.
3830 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3833 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3834 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3838 * This method returns the part of \a this having the geometric type \a gt.
3839 * If such part is not existing an exception will be thrown.
3840 * The returned pointer is **NOT** new object pointer. No need to mange it.
3842 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3845 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3846 int lev=(int)cm.getDimension()-getMeshDimension();
3847 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3848 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3852 * This method returns for each geo types in \a this number of cells with this geo type.
3853 * 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.
3854 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3856 * \sa getDistributionOfTypes
3858 std::vector< std::pair<int,mcIdType> > MEDFileUMesh::getAllDistributionOfTypes() const
3860 std::vector< std::pair<int,mcIdType> > ret;
3861 std::vector<int> nel(getNonEmptyLevels());
3862 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3864 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3865 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3867 mcIdType nbCells(getNumberOfCellsWithType(*it1));
3868 ret.push_back(std::pair<int,mcIdType>(*it1,nbCells));
3871 ret.push_back(std::pair<int,mcIdType>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3876 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3877 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3879 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3881 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3882 return sp->getGeoTypes();
3885 mcIdType MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3887 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3888 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3889 return sp->getNumberOfCellsWithType(ct);
3893 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3894 * \param [in] gt - the geometric type for which the family field is asked.
3895 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
3896 * delete using decrRef() as it is no more needed.
3897 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3899 DataArrayIdType *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3901 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3902 int lev=(int)cm.getDimension()-getMeshDimension();
3903 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3904 return sp->extractFamilyFieldOnGeoType(gt);
3908 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3909 * \param [in] gt - the geometric type for which the number field is asked.
3910 * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
3911 * delete using decrRef() as it is no more needed.
3912 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3914 DataArrayIdType *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3916 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3917 int lev=(int)cm.getDimension()-getMeshDimension();
3918 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3919 return sp->extractNumberFieldOnGeoType(gt);
3923 * This method returns for specified geometric type \a gt the relative level to \a this.
3924 * If the relative level is empty an exception will be thrown.
3926 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3928 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3929 int ret((int)cm.getDimension()-getMeshDimension());
3930 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3934 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3936 if(meshDimRelToMaxExt==1)
3937 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3938 if(meshDimRelToMaxExt>1)
3939 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3940 int tracucedRk=-meshDimRelToMaxExt;
3941 if(tracucedRk>=(int)_ms.size())
3942 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3943 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3944 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3945 return _ms[tracucedRk];
3948 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3950 if(meshDimRelToMaxExt==1)
3951 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3952 if(meshDimRelToMaxExt>1)
3953 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3954 int tracucedRk=-meshDimRelToMaxExt;
3955 if(tracucedRk>=(int)_ms.size())
3956 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3957 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3958 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3959 return _ms[tracucedRk];
3962 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3964 if(-meshDimRelToMax>=(int)_ms.size())
3965 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3967 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3969 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3971 int ref=(*it)->getMeshDimension();
3972 if(ref+i!=meshDim-meshDimRelToMax)
3973 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3979 * Sets the node coordinates array of \a this mesh.
3980 * \param [in] coords - the new node coordinates array.
3981 * \throw If \a coords == \c NULL.
3983 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3986 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3987 if(coords==(DataArrayDouble *)_coords)
3989 coords->checkAllocated();
3990 mcIdType nbOfTuples(coords->getNumberOfTuples());
3991 _coords.takeRef(coords);
3992 _fam_coords=DataArrayIdType::New();
3993 _fam_coords->alloc(nbOfTuples,1);
3994 _fam_coords->fillWithZero();
3995 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3996 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3997 if((MEDFileUMeshSplitL1 *)(*it))
3998 (*it)->setCoords(coords);
4002 * Change coords without changing anything concerning families and numbering on nodes.
4004 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
4007 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
4008 if(coords==(DataArrayDouble *)_coords)
4010 coords->checkAllocated();
4011 mcIdType nbOfTuples(coords->getNumberOfTuples());
4012 if(_coords.isNull())
4019 mcIdType oldNbTuples(_coords->getNumberOfTuples());
4020 if(oldNbTuples!=nbOfTuples)
4021 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
4025 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4026 if((MEDFileUMeshSplitL1 *)(*it))
4027 (*it)->setCoords(coords);
4031 * Removes all groups of a given dimension in \a this mesh.
4032 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4033 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4035 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
4037 if(meshDimRelToMaxExt==1)
4039 if((DataArrayIdType *)_fam_coords)
4040 _fam_coords->fillWithZero();
4043 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
4044 l1->eraseFamilyField();
4049 * Removes all families with ids not present in the family fields of \a this mesh.
4051 void MEDFileUMesh::optimizeFamilies()
4053 std::vector<int> levs=getNonEmptyLevelsExt();
4054 std::set<mcIdType> allFamsIds;
4055 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4057 const DataArrayIdType *ffield=getFamilyFieldAtLevel(*it);
4058 MCAuto<DataArrayIdType> ids=ffield->getDifferentValues();
4059 std::set<mcIdType> res;
4060 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
4063 std::set<std::string> famNamesToKill;
4064 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
4066 if(allFamsIds.find((*it).second)!=allFamsIds.end())
4067 famNamesToKill.insert((*it).first);
4069 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
4070 _families.erase(*it);
4071 std::vector<std::string> grpNamesToKill;
4072 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
4074 std::vector<std::string> tmp;
4075 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
4077 if(famNamesToKill.find(*it2)==famNamesToKill.end())
4078 tmp.push_back(*it2);
4083 tmp.push_back((*it).first);
4085 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
4090 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
4091 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
4092 * The boundary is built according to the following method:
4093 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
4094 * coordinates array is extended).
4095 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
4096 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
4097 * might not be duplicated at all.
4098 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
4099 * other side of the group is no more a neighbor)
4100 * - the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
4101 * bordering the newly created boundary use the newly computed nodes.
4102 * - finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
4103 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
4105 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
4106 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
4108 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
4109 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
4110 * \sa clearNodeAndCellNumbers()
4112 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayIdType *&nodesDuplicated,
4113 DataArrayIdType *&cellsModified, DataArrayIdType *&cellsNotModified)
4115 typedef MCAuto<MEDCouplingUMesh> MUMesh;
4116 typedef MCAuto<DataArrayIdType> DAInt;
4118 std::vector<int> levs=getNonEmptyLevels();
4119 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
4120 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
4121 MUMesh m0=getMeshAtLevel(0);
4122 MUMesh m1=getMeshAtLevel(-1);
4123 mcIdType nbNodes=m0->getNumberOfNodes();
4124 MUMesh m11=getGroup(-1,grpNameM1);
4125 DataArrayIdType *tmp00=0, *tmp11=0,*tmp22=0;
4127 // !!! The core of the duplication logic is in these 2 methods:
4129 DAInt nodeIdsToDuplicate = m0->findNodesToDuplicate(*m11); // identify nodes to duplicate
4130 m0->findCellsToRenumber(*m11, nodeIdsToDuplicate->begin(), nodeIdsToDuplicate->end(), tmp11,tmp22); // identify cells needing renumbering
4131 DAInt cellsToModifyConn0(tmp11);
4132 DAInt cellsToModifyConn1(tmp22);
4135 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
4136 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
4137 DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New();
4138 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
4139 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
4140 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
4141 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
4142 DataArrayIdType *cellsInM1ToRenumW4Tmp=0;
4143 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
4144 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
4145 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
4146 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
4147 DAInt grpIds=getGroupArr(-1,grpNameM1);
4148 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
4149 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
4150 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
4151 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
4152 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
4153 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
4154 m0->setCoords(tmp0->getCoords());
4155 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
4156 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
4157 m1->setCoords(m0->getCoords());
4158 _coords=m0->getCoords(); _coords->incrRef();
4159 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
4160 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
4161 DataArrayIdType * duplCells;
4162 m1->areCellsIncludedIn(m11, 0, duplCells);
4163 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
4164 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
4165 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
4166 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
4167 DAInt szOfCellGrpOfSameType(tmp00);
4168 DAInt idInMsOfCellGrpOfSameType(tmp11);
4170 newm1->setName(getName());
4171 const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
4173 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
4174 DAInt newFam=DataArrayIdType::New();
4175 newFam->alloc(newm1->getNumberOfCells(),1);
4176 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
4177 // Positive ID for family of nodes, negative for all the rest.
4179 if (m1->getMeshDimension() == 0)
4180 idd=getMaxFamilyId()+1;
4182 idd=getMinFamilyId()-1;
4183 mcIdType globStart=0,start=0,end,globEnd;
4184 mcIdType nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
4185 for(mcIdType i=0;i<nbOfChunks;i++)
4187 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4188 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4190 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4191 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4192 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4197 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4201 newm1->setCoords(getCoords());
4202 setMeshAtLevel(-1,newm1);
4203 setFamilyFieldArr(-1,newFam);
4204 std::string grpName2(grpNameM1); grpName2+="_dup";
4205 addFamily(grpName2,idd);
4206 addFamilyOnGrp(grpName2,grpName2);
4211 mcIdType newNbOfNodes=getCoords()->getNumberOfTuples();
4212 newFam=DataArrayIdType::New(); newFam->alloc(newNbOfNodes,1);
4213 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4214 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4218 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4220 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4221 it != _ms.end(); it++)
4224 (*it)->_rev_num = 0;
4226 nodesDuplicated=nodeIdsToDuplicate.retn();
4227 cellsModified=cellsToModifyConn0.retn();
4228 cellsNotModified=cellsToModifyConn1.retn();
4231 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4232 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4235 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4236 * \param [out] newCode retrieves the distribution of types after the call if true is returned
4237 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4239 * \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.
4240 * 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.
4242 bool MEDFileUMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
4244 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4245 std::vector<int> levs=getNonEmptyLevels();
4247 std::vector< const DataArrayIdType* > renumCellsSplited;//same than memorySaverIfThrow
4248 std::vector< MCAuto<DataArrayIdType> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4251 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4253 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4254 std::vector<mcIdType> code1=m->getDistributionOfTypes();
4255 end=PutInThirdComponentOfCodeOffset(code1,start);
4256 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4257 bool hasChanged=m->unPolyze();
4258 DataArrayIdType *fake=0;
4259 MCAuto<DataArrayIdType> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4260 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4262 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4265 MCAuto<DataArrayIdType> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4266 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4268 MCAuto<DataArrayIdType> famField2,numField2;
4269 const DataArrayIdType *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayIdType *>(famField); }
4270 const DataArrayIdType *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayIdType *>(numField); }
4271 setMeshAtLevel(*it,m);
4272 std::vector<mcIdType> code2=m->getDistributionOfTypes();
4273 end=PutInThirdComponentOfCodeOffset(code2,start);
4274 newCode.insert(newCode.end(),code2.begin(),code2.end());
4276 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4280 MCAuto<DataArrayIdType> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4281 setFamilyFieldArr(*it,newFamField);
4285 MCAuto<DataArrayIdType> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4286 setRenumFieldArr(*it,newNumField);
4291 newCode.insert(newCode.end(),code1.begin(),code1.end());
4297 MCAuto<DataArrayIdType> renumCells=DataArrayIdType::Aggregate(renumCellsSplited);
4298 MCAuto<DataArrayIdType> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4299 o2nRenumCell=o2nRenumCellRet.retn();
4304 /*! \cond HIDDEN_ITEMS */
4305 struct MEDLoaderAccVisit1
4307 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4308 mcIdType operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4309 mcIdType _new_nb_of_nodes;
4314 * 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.
4315 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4316 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4317 * -1 values in returned array means that the corresponding old node is no more used.
4319 * \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
4320 * is modified in \a this.
4321 * \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
4324 DataArrayIdType *MEDFileUMesh::zipCoords()
4326 const DataArrayDouble *coo(getCoords());
4328 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4329 mcIdType nbOfNodes(coo->getNumberOfTuples());
4330 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4331 std::vector<int> neLevs(getNonEmptyLevels());
4332 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4334 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4335 if(zeLev->isMeshStoredSplitByType())
4337 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4338 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4340 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4344 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4345 mesh->computeNodeIdsAlg(nodeIdsInUse);
4348 mcIdType nbrOfNodesInUse((mcIdType)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4349 if(nbrOfNodesInUse==nbOfNodes)
4350 return 0;//no need to update _part_coords
4351 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfNodes,1);
4352 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4353 MCAuto<DataArrayIdType> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4354 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4355 MCAuto<DataArrayIdType> newFamCoords;
4356 MCAuto<DataArrayAsciiChar> newNameCoords;
4357 if((const DataArrayIdType *)_fam_coords)
4358 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4359 MCAuto<DataArrayIdType> newNumCoords,newGlobalNumCoords;
4360 if(_num_coords.isNotNull())
4361 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4362 if(_global_num_coords.isNotNull())
4363 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4364 if(_name_coords.isNotNull())
4365 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4366 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4367 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4369 if((MEDFileUMeshSplitL1*)*it)
4371 (*it)->renumberNodesInConn(ret->begin());
4372 (*it)->setCoords(_coords);
4375 // updates _part_coords
4376 const PartDefinition *pc(_part_coords);
4379 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4380 _part_coords=tmpPD->composeWith(pc);
4386 * This method is the extension of MEDCouplingUMesh::computeFetchedNodeIds. Except that here all levels are considered here.
4388 * \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.
4390 DataArrayIdType *MEDFileUMesh::computeFetchedNodeIds() const
4392 std::vector<int> neLevs(this->getNonEmptyLevels());
4393 std::vector<bool> nodesHighlighted(this->getNumberOfNodes(),false);
4394 for(auto lev : neLevs)
4396 const MEDFileUMeshSplitL1 *zeLev(this->getMeshAtLevSafe(lev));
4397 zeLev->highlightUsedNodes(nodesHighlighted);
4399 return DataArrayIdType::BuildListOfSwitchedOn(nodesHighlighted);
4403 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4404 * The extraction of \a this is specified by the extractDef \a input map.
4405 * This map tells for each level of cells, the cells kept in the extraction.
4407 * \return - a new reference of DataArrayIdType that represents sorted node ids, the extraction is lying on.
4408 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4410 DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4412 std::vector<int> levs(getNonEmptyLevels());
4413 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4414 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4417 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4418 if((*it).second.isNull())
4419 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4422 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4424 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4425 throw INTERP_KERNEL::Exception(oss.str());
4427 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4428 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4429 mPart->computeNodeIdsAlg(fetchedNodes);
4431 return DataArrayIdType::BuildListOfSwitchedOn(fetchedNodes);
4435 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4437 * \return - a new reference of MEDFileUMesh
4438 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4440 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
4442 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4443 std::vector<int> levs(getNonEmptyLevels());
4444 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4447 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4448 if((*it).second.isNull())
4449 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4452 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4454 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4455 throw INTERP_KERNEL::Exception(oss.str());
4457 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4458 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4459 ret->setMeshAtLevel((*it).first,mPart);
4460 const DataArrayIdType *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4463 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4464 ret->setFamilyFieldArr((*it).first,famPart);
4468 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4469 ret->setFamilyFieldArr((*it).first,numPart);
4472 std::map<int, MCAuto<DataArrayIdType> >::const_iterator it2(extractDef.find(1));
4473 if(it2!=extractDef.end())
4475 const DataArrayDouble *coo(ret->getCoords());
4477 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4478 MCAuto<DataArrayIdType> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4479 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4480 ret->setCoords(cooPart);
4481 const DataArrayIdType *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4484 MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4485 ret->setFamilyFieldArr(1,famPart);
4489 MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4490 ret->setFamilyFieldArr(1,numPart);
4492 for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4496 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4497 m->renumberNodesInConn(o2nNodes->begin());
4498 ret->setMeshAtLevel((*it3).first,m);
4505 * This method performs an extrusion along a path defined by \a m1D.
4506 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4507 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4508 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4509 * This method scans all levels in \a this
4510 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4512 * \param [in] m1D - the mesh defining the extrusion path.
4513 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4514 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4516 * \sa MEDCouplingUMesh::buildExtrudedMesh
4518 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4521 if(getMeshDimension()!=2)
4522 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4523 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4524 m1D->checkConsistencyLight();
4525 if(m1D->getMeshDimension()!=1)
4526 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4527 mcIdType nbRep(m1D->getNumberOfCells());
4528 std::vector<int> levs(getNonEmptyLevels());
4529 std::vector<std::string> grps(getGroupsNames());
4530 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4531 DataArrayDouble *coords(0);
4532 std::size_t nbOfLevsOut(levs.size()+1);
4533 std::vector< MCAuto<DataArrayIdType> > o2ns(nbOfLevsOut);
4534 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4536 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4537 item=item->clone(false);
4538 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4539 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4540 tmp->changeSpaceDimension(3+(*lev),0.);
4541 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4542 zeList.push_back(elt);
4544 coords=elt->getCoords();
4547 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4548 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4550 (*it)->setName(getName());
4551 (*it)->setCoords(coords);
4553 for(std::size_t ii=0;ii!=zeList.size();ii++)
4556 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4559 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4560 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4561 MCAuto<DataArrayIdType> tmp(elt2->getNodalConnectivity()->deepCopy());
4562 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4563 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4564 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4565 std::vector<const MEDCouplingUMesh *> elts(3);
4566 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4567 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4568 elt->setName(getName());
4571 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4572 ret->setMeshAtLevel(lev,elt);
4574 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4575 endLev=endLev->clone(false); endLev->setCoords(coords);
4576 MCAuto<DataArrayIdType> tmp(endLev->getNodalConnectivity()->deepCopy());
4577 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4578 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4579 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4580 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4581 endLev->setName(getName());
4582 ret->setMeshAtLevel(levs.back()-1,endLev);
4584 for(std::size_t ii=0;ii!=zeList.size();ii++)
4587 std::vector< MCAuto<DataArrayIdType> > outGrps;
4588 std::vector< const DataArrayIdType * > outGrps2;
4591 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4593 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev+1,*grp));
4594 if(!grpArr->empty())
4596 MCAuto<DataArrayIdType> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4597 mcIdType offset0(zeList[ii]->getNumberOfCells());
4598 mcIdType offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4599 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4600 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4601 grpArr2->setName(oss.str());
4602 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4603 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4604 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4605 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4610 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4612 MCAuto<DataArrayIdType> grpArr(getGroupArr(lev,*grp));
4613 if(!grpArr->empty())
4615 mcIdType nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4616 std::vector< MCAuto<DataArrayIdType> > grpArrs(nbRep);
4617 std::vector< const DataArrayIdType *> grpArrs2(nbRep);
4618 for(int iii=0;iii<nbRep;iii++)
4620 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4621 grpArrs2[iii]=grpArrs[iii];
4623 MCAuto<DataArrayIdType> grpArrExt(DataArrayIdType::Aggregate(grpArrs2));
4624 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4625 std::ostringstream grpName; grpName << *grp << "_extruded";
4626 grpArrExt->setName(grpName.str());
4627 outGrps.push_back(grpArrExt);
4628 outGrps2.push_back(grpArrExt);
4631 ret->setGroupsAtLevel(lev,outGrps2);
4633 std::vector< MCAuto<DataArrayIdType> > outGrps;
4634 std::vector< const DataArrayIdType * > outGrps2;
4635 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4637 MCAuto<DataArrayIdType> grpArr1(getGroupArr(levs.back(),*grp));
4638 if(grpArr1->empty())
4640 MCAuto<DataArrayIdType> grpArr2(grpArr1->deepCopy());
4641 std::ostringstream grpName; grpName << *grp << "_top";
4642 grpArr2->setName(grpName.str());
4643 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4644 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4645 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4647 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4652 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4653 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4654 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4656 * \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
4657 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4658 * \param [in] eps - detection threshold for coordinates.
4659 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4661 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4663 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4666 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4667 mcIdType initialNbNodes(getNumberOfNodes());
4668 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4669 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4671 MCAuto<DataArrayIdType> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4673 DataArrayDouble *zeCoords(m0->getCoords());
4674 ret->setMeshAtLevel(0,m0);
4675 std::vector<int> levs(getNonEmptyLevels());
4676 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4679 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4680 ret->setFamilyFieldArr(0,famFieldCpy);
4682 famField=getFamilyFieldAtLevel(1);
4685 MCAuto<DataArrayIdType> fam(DataArrayIdType::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4686 fam->fillWithZero();
4687 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4688 ret->setFamilyFieldArr(1,fam);
4690 ret->copyFamGrpMapsFrom(*this);
4691 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4692 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4696 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4697 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4698 if(m1->getMeshDimension()!=0)
4701 MCAuto<DataArrayIdType> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4702 }//kill unused notUsed var
4703 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4704 DataArrayIdType *b(0);
4705 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4706 MCAuto<DataArrayIdType> bSafe(b);
4709 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4710 throw INTERP_KERNEL::Exception(oss.str().c_str());
4712 b->applyLin(1,initialNbNodes);
4713 MCAuto<DataArrayIdType> l0(DataArrayIdType::New()); l0->alloc(initialNbNodes,1); l0->iota();
4714 std::vector<const DataArrayIdType *> v(2); v[0]=l0; v[1]=b;
4715 MCAuto<DataArrayIdType> renum(DataArrayIdType::Aggregate(v));
4716 m1->renumberNodesInConn(renum->begin());
4718 m1->setCoords(zeCoords);
4719 ret->setMeshAtLevel(*lev,m1);
4720 famField=getFamilyFieldAtLevel(*lev);
4723 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4724 ret->setFamilyFieldArr(*lev,famFieldCpy);
4731 * This method converts all quadratic cells in \a this into linear cells.
4732 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4733 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4735 * \param [in] eps - detection threshold for coordinates.
4736 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4738 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4740 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4743 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4744 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4745 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4746 m0->convertQuadraticCellsToLinear();
4748 DataArrayDouble *zeCoords(m0->getCoords());
4749 ret->setMeshAtLevel(0,m0);
4750 std::vector<int> levs(getNonEmptyLevels());
4751 const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
4754 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4755 ret->setFamilyFieldArr(0,famFieldCpy);
4757 famField=getFamilyFieldAtLevel(1);
4760 MCAuto<DataArrayIdType> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4761 ret->setFamilyFieldArr(1,fam);
4763 ret->copyFamGrpMapsFrom(*this);
4764 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4768 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4769 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4770 m1->convertQuadraticCellsToLinear();
4772 DataArrayIdType *b(0);
4773 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4774 MCAuto<DataArrayIdType> bSafe(b);
4777 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4778 throw INTERP_KERNEL::Exception(oss.str().c_str());
4780 m1->renumberNodesInConn(b->begin());
4781 m1->setCoords(zeCoords);
4782 ret->setMeshAtLevel(*lev,m1);
4783 famField=getFamilyFieldAtLevel(*lev);
4786 MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
4787 ret->setFamilyFieldArr(*lev,famFieldCpy);
4794 * Computes the symmetry of \a this.
4795 * \return a new object.
4797 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4799 MCAuto<MEDFileUMesh> ret(deepCopy());
4800 DataArrayDouble *myCoo(getCoords());
4803 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4804 ret->setCoordsForced(newCoo);
4810 * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
4811 * merged in such a way that the final mesh contain all of them.
4812 * \return a new object.
4814 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4817 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4818 std::size_t sz(meshes.size()),i(0);
4819 std::vector<const DataArrayDouble *> coos(sz);
4820 std::vector<const DataArrayIdType *> fam_coos(sz),num_coos(sz);
4821 for(auto it=meshes.begin();it!=meshes.end();it++,i++)
4824 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4825 coos[i]=(*it)->getCoords();
4826 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4827 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4829 const MEDFileUMesh *ref(meshes[0]);
4830 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4831 std::vector<int> levs(ref->getNonEmptyLevels());
4832 std::map<int, std::vector<const DataArrayIdType *> > m_fam,m_renum;
4833 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4834 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4835 std::map<std::string,mcIdType> famNumMap;
4836 std::map<mcIdType, std::string> famNumMap_rev;
4837 std::map<std::string, std::vector<std::string> > grpFamMap;
4838 std::set< MCAuto<DataArrayIdType> > mem_cleanup; // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
4840 // Identify min family number used:
4841 mcIdType min_fam_num(0);
4842 for(const auto& msh : meshes)
4844 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4845 for(const auto& it3 : locMap1)
4846 if(it3.second < min_fam_num)
4847 min_fam_num = it3.second;
4850 for(const auto& msh : meshes)
4852 if(msh->getSpaceDimension()!=spaceDim)
4853 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4854 if(msh->getMeshDimension()!=meshDim)
4855 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4856 if(msh->getNonEmptyLevels()!=levs)
4857 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4859 const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
4860 std::map<std::string, std::string> substitute;
4861 std::map<mcIdType, mcIdType> substituteN;
4862 bool fam_conflict(false);
4863 for(const auto& it3 : locMap1)
4865 const std::string& famName = it3.first;
4866 mcIdType famNum = it3.second;
4867 if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
4869 // Is it used by a group of the current mesh or a group from a previous mesh?
4870 // If not, this is OK (typically -1 familly).
4873 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4874 for(const auto& it4 : locMap2)
4876 const auto& famLst = it4.second;
4877 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4878 { used = true; break; }
4880 // Previous meshes ...
4882 for(const auto& it4 : grpFamMap)
4884 const auto& famLst = it4.second;
4885 if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
4886 { used = true; break; }
4890 { // Generate a new family name, and a new family number
4891 fam_conflict = true;
4892 std::ostringstream oss;
4893 oss << "Family_" << --min_fam_num; // New ID
4894 std::string new_name(oss.str());
4895 substitute[famName] = new_name;
4896 substituteN[famNum] = min_fam_num;
4897 famNumMap[new_name] = min_fam_num;
4898 famNumMap_rev[min_fam_num] = new_name;
4901 famNumMap[famName] = famNum;
4902 famNumMap_rev[famNum] = famName;
4905 for(const auto& level : levs)
4907 MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
4908 m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
4909 m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
4911 // Family field - substitute new family number if needed:
4914 DataArrayIdType* dai(msh->getFamilyFieldAtLevel(level)->deepCopy()); // Need a copy
4915 mem_cleanup.insert(MCAuto<DataArrayIdType>(dai)); // Make sure array will decrRef() at end of method
4916 for (const auto& subN : substituteN)
4917 dai->changeValue(subN.first, subN.second);
4918 m_fam[level].push_back(dai);
4921 m_fam[level].push_back(msh->getFamilyFieldAtLevel(level)); // No copy needed
4924 const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
4925 for(const auto& grpItem : locMap2)
4927 const std::string& grpName = grpItem.first;
4928 std::vector<std::string> famLst;
4929 // Substitute family name in group description if needed:
4932 famLst = grpItem.second;
4933 for (const auto& sub : substitute)
4934 std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
4937 famLst = grpItem.second;
4939 // Potentially merge groups (if same name):
4940 const auto& it = grpFamMap.find(grpName);
4941 if (it != grpFamMap.end())
4943 // Group already exists, merge should be done. Normally we whould never
4944 // have twice the same family name in famLstCur and famLst since we dealt with family number
4945 // conflict just above ...
4946 std::vector<std::string>& famLstCur = (*it).second;
4947 famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
4950 grpFamMap[grpName] = famLst;
4953 // Easy part : nodes
4954 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4955 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4956 ret->setCoords(coo);
4957 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayIdType *)0)==fam_coos.end())
4959 MCAuto<DataArrayIdType> fam_coo(DataArrayIdType::Aggregate(fam_coos));
4960 ret->setFamilyFieldArr(1,fam_coo);
4962 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayIdType *)0)==num_coos.end())
4964 MCAuto<DataArrayIdType> num_coo(DataArrayIdType::Aggregate(num_coos));
4965 ret->setRenumFieldArr(1,num_coo);
4968 for(const auto& level : levs)
4970 auto it2(m_mesh.find(level));
4971 if(it2==m_mesh.end())
4972 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4973 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4974 mesh->setCoords(coo); mesh->setName(ref->getName());
4975 MCAuto<DataArrayIdType> renum(mesh->sortCellsInMEDFileFrmt());
4976 ret->setMeshAtLevel(level,mesh);
4977 auto it3(m_fam.find(level)),it4(m_renum.find(level));
4978 if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
4979 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
4980 if(it4==m_renum.end())
4981 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
4982 // Set new family field if it was defined for all input meshes
4983 const std::vector<const DataArrayIdType *>& fams((*it3).second);
4984 if(std::find(fams.begin(),fams.end(),(const DataArrayIdType *)0)==fams.end())
4986 MCAuto<DataArrayIdType> famm(DataArrayIdType::Aggregate(fams));
4987 famm->renumberInPlace(renum->begin());
4988 ret->setFamilyFieldArr(level,famm);
4990 // Set optional number field if defined for all input meshes:
4991 const std::vector<const DataArrayIdType *>& renums((*it4).second);
4992 if(std::find(renums.begin(),renums.end(),(const DataArrayIdType *)0)==renums.end())
4994 MCAuto<DataArrayIdType> renumm(DataArrayIdType::Aggregate(renums));
4995 renumm->renumberInPlace(renum->begin());
4996 ret->setRenumFieldArr(level,renumm);
5000 ret->setFamilyInfo(famNumMap);
5001 ret->setGroupInfo(grpFamMap);
5002 ret->setName(ref->getName());
5006 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
5008 if(getMeshDimension()!=3)
5009 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
5010 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
5011 if(m3D.isNull() || m2D.isNull())
5012 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
5013 mcIdType zeId(std::numeric_limits<med_int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
5014 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
5018 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5020 clearNonDiscrAttributes();
5021 forceComputationOfParts();
5022 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
5023 std::vector<mcIdType> layer0;
5024 layer0.push_back(getAxisType());//0 i
5025 layer0.push_back(_order); //1 i
5026 layer0.push_back(_iteration);//2 i
5027 layer0.push_back(getSpaceDimension());//3 i
5028 tinyDouble.push_back(_time);//0 d
5029 tinyStr.push_back(_name);//0 s
5030 tinyStr.push_back(_desc_name);//1 s
5031 for(int i=0;i<getSpaceDimension();i++)
5032 tinyStr.push_back(_coords->getInfoOnComponent(i));
5033 layer0.push_back(ToIdType(_families.size()));//4 i <- key info aa layer#0
5034 for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
5036 tinyStr.push_back((*it).first);
5037 layer0.push_back((*it).second);
5039 layer0.push_back((mcIdType)_groups.size());//4+aa i <- key info bb layer#0
5040 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
5042 layer0.push_back(ToIdType((*it0).second.size()));
5043 tinyStr.push_back((*it0).first);
5044 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
5045 tinyStr.push_back(*it1);
5047 // sizeof(layer0)==4+aa+1+bb layer#0
5048 bigArrayD=_coords;// 0 bd
5049 bigArraysI.push_back(_fam_coords);// 0 bi
5050 bigArraysI.push_back(_num_coords);// 1 bi
5051 const PartDefinition *pd(_part_coords);
5053 layer0.push_back(-1);
5056 std::vector<mcIdType> tmp0;
5057 pd->serialize(tmp0,bigArraysI);
5058 tinyInt.push_back(ToIdType(tmp0.size()));
5059 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
5062 std::vector<mcIdType> layer1;
5063 std::vector<int> levs(getNonEmptyLevels());
5064 layer1.push_back((mcIdType)levs.size());// 0 i <- key
5065 layer1.insert(layer1.end(),levs.begin(),levs.end());
5066 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
5068 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
5069 lev->serialize(layer1,bigArraysI);
5071 // put layers all together.
5072 tinyInt.push_back(ToIdType(layer0.size()));
5073 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
5074 tinyInt.push_back(ToIdType(layer1.size()));
5075 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
5078 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr,
5079 std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
5081 mcIdType sz0(tinyInt[0]);
5082 std::vector<mcIdType> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
5083 mcIdType sz1(tinyInt[sz0+1]);
5084 std::vector<mcIdType> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
5086 std::reverse(layer0.begin(),layer0.end());
5087 std::reverse(layer1.begin(),layer1.end());
5088 std::reverse(tinyDouble.begin(),tinyDouble.end());
5089 std::reverse(tinyStr.begin(),tinyStr.end());
5090 std::reverse(bigArraysI.begin(),bigArraysI.end());
5092 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
5093 _order=FromIdType<int>(layer0.back()); layer0.pop_back();
5094 _iteration=FromIdType<int>(layer0.back()); layer0.pop_back();
5095 mcIdType spaceDim(layer0.back()); layer0.pop_back();
5096 _time=tinyDouble.back(); tinyDouble.pop_back();
5097 _name=tinyStr.back(); tinyStr.pop_back();
5098 _desc_name=tinyStr.back(); tinyStr.pop_back();
5099 _coords=bigArrayD; _coords->rearrange(spaceDim);
5100 for(int i=0;i<spaceDim;i++)
5102 _coords->setInfoOnComponent(i,tinyStr.back());
5105 mcIdType nbOfFams(layer0.back()); layer0.pop_back();
5107 for(mcIdType i=0;i<nbOfFams;i++)
5109 _families[tinyStr.back()]=layer0.back();
5110 tinyStr.pop_back(); layer0.pop_back();
5112 mcIdType nbGroups(layer0.back()); layer0.pop_back();
5114 for(mcIdType i=0;i<nbGroups;i++)
5116 std::string grpName(tinyStr.back()); tinyStr.pop_back();
5117 mcIdType nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
5118 std::vector<std::string> fams(nbOfFamsOnGrp);
5119 for(mcIdType j=0;j<nbOfFamsOnGrp;j++)
5121 fams[j]=tinyStr.back(); tinyStr.pop_back();
5123 _groups[grpName]=fams;
5125 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
5126 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
5128 mcIdType isPd(layer0.back()); layer0.pop_back();
5131 std::vector<mcIdType> tmp0(layer0.begin(),layer0.begin()+isPd);
5132 layer0.erase(layer0.begin(),layer0.begin()+isPd);
5133 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
5136 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
5138 mcIdType nbLevs(layer1.back()); layer1.pop_back();
5139 std::vector<mcIdType> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
5141 mcIdType maxLev(-(*std::min_element(levs.begin(),levs.end())));
5142 _ms.resize(maxLev+1);
5143 for(mcIdType i=0;i<nbLevs;i++)
5145 mcIdType lev(levs[i]);
5147 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
5152 * Adds a group of nodes to \a this mesh.
5153 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5154 * The ids should be sorted and different each other (MED file norm).
5156 * \warning this method can alter default "FAMILLE_ZERO" family.
5157 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5159 * \throw If the node coordinates array is not set.
5160 * \throw If \a ids == \c NULL.
5161 * \throw If \a ids->getName() == "".
5162 * \throw If \a ids does not respect the MED file norm.
5163 * \throw If a group with name \a ids->getName() already exists.
5165 void MEDFileUMesh::addNodeGroup(const DataArrayIdType *ids)
5167 const DataArrayDouble *coords(_coords);
5169 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
5170 mcIdType nbOfNodes(coords->getNumberOfTuples());
5171 if(_fam_coords.isNull())
5172 { _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
5174 addGroupUnderground(true,ids,_fam_coords);
5178 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5180 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
5181 * The ids should be sorted and different each other (MED file norm).
5183 * \warning this method can alter default "FAMILLE_ZERO" family.
5184 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5186 * \throw If the node coordinates array is not set.
5187 * \throw If \a ids == \c NULL.
5188 * \throw If \a ids->getName() == "".
5189 * \throw If \a ids does not respect the MED file norm.
5190 * \throw If a group with name \a ids->getName() already exists.
5192 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
5194 std::vector<int> levs(getNonEmptyLevelsExt());
5195 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
5197 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
5198 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
5200 if(meshDimRelToMaxExt==1)
5201 { addNodeGroup(ids); return ; }
5202 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
5203 DataArrayIdType *fam(lev->getOrCreateAndGetFamilyField());
5204 addGroupUnderground(false,ids,fam);
5208 * Changes a name of a family specified by its id.
5209 * \param [in] id - the id of the family of interest.
5210 * \param [in] newFamName - the new family name.
5211 * \throw If no family with the given \a id exists.
5213 void MEDFileUMesh::setFamilyNameAttachedOnId(mcIdType id, const std::string& newFamName)
5215 std::string oldName=getFamilyNameGivenId(id);
5216 _families.erase(oldName);
5217 _families[newFamName]=id;
5221 * Removes a mesh of a given dimension.
5222 * \param [in] meshDimRelToMax - the relative dimension of interest.
5223 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
5225 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
5227 std::vector<int> levSet=getNonEmptyLevels();
5228 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
5229 if(it==levSet.end())
5230 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
5231 int pos=(-meshDimRelToMax);
5236 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
5237 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5238 * \param [in] m - the new mesh to set.
5239 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5241 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5242 * another node coordinates array.
5243 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5244 * to the existing meshes of other levels of \a this mesh.
5246 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
5248 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
5249 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5253 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
5254 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
5255 * \param [in] m - the new mesh to set.
5256 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
5257 * writing \a this mesh in a MED file.
5258 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5260 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
5261 * another node coordinates array.
5262 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
5263 * to the existing meshes of other levels of \a this mesh.
5265 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
5267 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
5268 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
5271 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
5273 dealWithTinyInfo(m);
5274 std::vector<int> levSet=getNonEmptyLevels();
5275 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
5277 if((DataArrayDouble *)_coords==0)
5279 DataArrayDouble *c=m->getCoords();
5284 if(m->getCoords()!=_coords)
5285 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
5286 int sz=(-meshDimRelToMax)+1;
5287 if(sz>=(int)_ms.size())
5289 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
5293 return _ms[-meshDimRelToMax];
5297 * This method allows to set at once the content of different levels in \a this.
5298 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
5300 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
5301 * \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.
5302 * If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
5304 * \throw If \a there is a null pointer in \a ms.
5305 * \sa MEDFileUMesh::setMeshAtLevel
5307 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5311 const MEDCouplingUMesh *mRef=ms[0];
5313 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5314 std::string name(mRef->getName());
5315 const DataArrayDouble *coo(mRef->getCoords());
5318 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5320 const MEDCouplingUMesh *cur(*it);
5322 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5323 if(coo!=cur->getCoords())
5324 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5325 int mdim=cur->getMeshDimension();
5326 zeDim=std::max(zeDim,mdim);
5327 if(s.find(mdim)!=s.end())
5328 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5330 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5332 int mdim=(*it)->getMeshDimension();
5333 setName((*it)->getName());
5334 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5340 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5341 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5342 * The given meshes must share the same node coordinates array.
5343 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5344 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5345 * create in \a this mesh.
5346 * \throw If \a ms is empty.
5347 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5348 * to the existing meshes of other levels of \a this mesh.
5349 * \throw If the meshes in \a ms do not share the same node coordinates array.
5350 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5351 * of the given meshes.
5352 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5353 * \throw If names of some meshes in \a ms are equal.
5354 * \throw If \a ms includes a mesh with an empty name.
5356 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5359 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5360 int sz=(-meshDimRelToMax)+1;
5361 if(sz>=(int)_ms.size())
5363 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5364 DataArrayDouble *coo=checkMultiMesh(ms);
5365 if((DataArrayDouble *)_coords==0)
5371 if((DataArrayDouble *)_coords!=coo)
5372 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5373 std::vector<DataArrayIdType *> corr;
5374 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5375 std::vector< MCAuto<DataArrayIdType> > corr3(corr.begin(),corr.end());
5376 setMeshAtLevel(meshDimRelToMax,m,renum);
5377 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5378 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5382 * Creates groups at a given level in \a this mesh from a sequence of
5383 * meshes each representing a group.
5384 * The given meshes must share the same node coordinates array.
5385 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5386 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5387 * create in \a this mesh.
5388 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5390 * \throw If \a ms is empty.
5391 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5392 * to the existing meshes of other levels of \a this mesh.
5393 * \throw If the meshes in \a ms do not share the same node coordinates array.
5394 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5395 * of the given meshes.
5396 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5397 * \throw If names of some meshes in \a ms are equal.
5398 * \throw If \a ms includes a mesh with an empty name.
5400 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5403 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5404 int sz=(-meshDimRelToMax)+1;
5405 if(sz>=(int)_ms.size())
5407 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5408 DataArrayDouble *coo=checkMultiMesh(ms);
5409 if((DataArrayDouble *)_coords==0)
5415 if((DataArrayDouble *)_coords!=coo)
5416 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5417 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5418 std::vector< MCAuto<DataArrayIdType> > corr(ms.size());
5420 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5422 DataArrayIdType *arr=0;
5423 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5427 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5428 throw INTERP_KERNEL::Exception(oss.str().c_str());
5431 std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
5432 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5435 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5437 const DataArrayDouble *ret=ms[0]->getCoords();
5438 int mdim=ms[0]->getMeshDimension();
5439 for(unsigned int i=1;i<ms.size();i++)
5441 ms[i]->checkConsistencyLight();
5442 if(ms[i]->getCoords()!=ret)
5443 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5444 if(ms[i]->getMeshDimension()!=mdim)
5445 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5447 return const_cast<DataArrayDouble *>(ret);
5451 * Sets the family field of a given relative dimension.
5452 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5453 * the family field is set.
5454 * \param [in] famArr - the array of the family field.
5455 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5456 * \throw If \a famArr has an invalid size.
5458 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5460 if(meshDimRelToMaxExt==1)
5467 DataArrayDouble *coo(_coords);
5469 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5470 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5471 _fam_coords.takeRef(famArr);
5474 if(meshDimRelToMaxExt>1)
5475 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5476 int traducedRk=-meshDimRelToMaxExt;
5477 if(traducedRk>=(int)_ms.size())
5478 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5479 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5480 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5481 return _ms[traducedRk]->setFamilyArr(famArr);
5485 * Sets the optional numbers of mesh entities of a given dimension.
5486 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5487 * \param [in] renumArr - the array of the numbers.
5488 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5489 * \throw If \a renumArr has an invalid size.
5491 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
5493 if(meshDimRelToMaxExt==1)
5497 _num_coords.nullify();
5498 _rev_num_coords.nullify();
5501 if(_coords.isNull())
5502 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5503 renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5504 _num_coords.takeRef(renumArr);
5507 if(meshDimRelToMaxExt>1)
5508 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5509 int traducedRk=-meshDimRelToMaxExt;
5510 if(traducedRk>=(int)_ms.size())
5511 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5512 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5513 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5514 return _ms[traducedRk]->setRenumArr(renumArr);
5518 * Sets the optional names of mesh entities of a given dimension.
5519 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5520 * \param [in] nameArr - the array of the names.
5521 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5522 * \throw If \a nameArr has an invalid size.
5524 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5526 if(meshDimRelToMaxExt==1)
5533 DataArrayDouble *coo(_coords);
5535 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5536 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5537 _name_coords.takeRef(nameArr);
5540 if(meshDimRelToMaxExt>1)
5541 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5542 int traducedRk=-meshDimRelToMaxExt;
5543 if(traducedRk>=(int)_ms.size())
5544 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5545 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5546 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5547 return _ms[traducedRk]->setNameArr(nameArr);
5550 void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
5552 if(meshDimRelToMaxExt!=1)
5553 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
5555 globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
5556 _global_num_coords.takeRef(globalNumArr);
5559 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5561 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5562 if((const MEDFileUMeshSplitL1 *)(*it))
5563 (*it)->synchronizeTinyInfo(*this);
5567 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5569 void MEDFileUMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
5571 DataArrayIdType *arr=_fam_coords;
5573 arr->changeValue(oldId,newId);
5574 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5576 MEDFileUMeshSplitL1 *sp=(*it);
5579 sp->changeFamilyIdArr(oldId,newId);
5584 std::list< MCAuto<DataArrayIdType> > MEDFileUMesh::getAllNonNullFamilyIds() const
5586 std::list< MCAuto<DataArrayIdType> > ret;
5587 const DataArrayIdType *da(_fam_coords);
5589 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5590 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5592 const MEDFileUMeshSplitL1 *elt(*it);
5595 da=elt->getFamilyField();
5597 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
5603 void MEDFileUMesh::computeRevNum() const
5605 if(_num_coords.isNotNull())
5608 mcIdType maxValue=_num_coords->getMaxValue(pos);
5609 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5613 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5615 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5618 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5620 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5621 ret.push_back((const DataArrayIdType *)_fam_nodes);
5622 ret.push_back((const DataArrayIdType *)_num_nodes);
5623 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5624 ret.push_back((const DataArrayIdType *)_fam_cells);
5625 ret.push_back((const DataArrayIdType *)_num_cells);
5626 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5627 ret.push_back((const DataArrayIdType *)_fam_faces);
5628 ret.push_back((const DataArrayIdType *)_num_faces);
5629 ret.push_back((const DataArrayIdType *)_rev_num_nodes);
5630 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5631 ret.push_back((const DataArrayIdType *)_rev_num_cells);
5632 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5636 mcIdType MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5638 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5639 if((const DataArrayIdType *)_fam_nodes)
5641 mcIdType val=_fam_nodes->getMaxValue(tmp);
5642 ret=std::max(ret,std::abs(val));
5644 if((const DataArrayIdType *)_fam_cells)
5646 mcIdType val=_fam_cells->getMaxValue(tmp);
5647 ret=std::max(ret,std::abs(val));
5649 if((const DataArrayIdType *)_fam_faces)
5651 mcIdType val=_fam_faces->getMaxValue(tmp);
5652 ret=std::max(ret,std::abs(val));
5657 mcIdType MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5659 mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
5660 if((const DataArrayIdType *)_fam_nodes)
5662 mcIdType val=_fam_nodes->getMaxValue(tmp);
5663 ret=std::max(ret,val);
5665 if((const DataArrayIdType *)_fam_cells)
5667 mcIdType val=_fam_cells->getMaxValue(tmp);
5668 ret=std::max(ret,val);
5670 if((const DataArrayIdType *)_fam_faces)
5672 mcIdType val=_fam_faces->getMaxValue(tmp);
5673 ret=std::max(ret,val);
5678 mcIdType MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5680 mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
5681 if((const DataArrayIdType *)_fam_nodes)
5683 mcIdType val=_fam_nodes->getMinValue(tmp);
5684 ret=std::min(ret,val);
5686 if((const DataArrayIdType *)_fam_cells)
5688 mcIdType val=_fam_cells->getMinValue(tmp);
5689 ret=std::min(ret,val);
5691 if((const DataArrayIdType *)_fam_faces)
5693 mcIdType val=_fam_faces->getMinValue(tmp);
5694 ret=std::min(ret,val);
5699 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5701 if(!MEDFileMesh::isEqual(other,eps,what))
5703 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5706 what="Mesh types differ ! This is structured and other is NOT !";
5709 const DataArrayIdType *famc1=_fam_nodes;
5710 const DataArrayIdType *famc2=otherC->_fam_nodes;
5711 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5713 what="Mismatch of families arr on nodes ! One is defined and not other !";
5718 bool ret=famc1->isEqual(*famc2);
5721 what="Families arr on nodes differ !";
5726 famc2=otherC->_fam_cells;
5727 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5729 what="Mismatch of families arr on cells ! One is defined and not other !";
5734 bool ret=famc1->isEqual(*famc2);
5737 what="Families arr on cells differ !";
5742 famc2=otherC->_fam_faces;
5743 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5745 what="Mismatch of families arr on faces ! One is defined and not other !";
5750 bool ret=famc1->isEqual(*famc2);
5753 what="Families arr on faces differ !";
5758 famc2=otherC->_num_nodes;
5759 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5761 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5766 bool ret=famc1->isEqual(*famc2);
5769 what="Numbering arr on nodes differ !";
5774 famc2=otherC->_num_cells;
5775 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5777 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5782 bool ret=famc1->isEqual(*famc2);
5785 what="Numbering arr on cells differ !";
5790 famc2=otherC->_num_faces;
5791 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5793 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5798 bool ret=famc1->isEqual(*famc2);
5801 what="Numbering arr on faces differ !";
5805 const DataArrayAsciiChar *d1=_names_cells;
5806 const DataArrayAsciiChar *d2=otherC->_names_cells;
5807 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5809 what="Mismatch of naming arr on cells ! One is defined and not other !";
5814 bool ret=d1->isEqual(*d2);
5817 what="Naming arr on cells differ !";
5822 d2=otherC->_names_faces;
5823 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5825 what="Mismatch of naming arr on faces ! One is defined and not other !";
5830 bool ret=d1->isEqual(*d2);
5833 what="Naming arr on faces differ !";
5838 d2=otherC->_names_nodes;
5839 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5841 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5846 bool ret=d1->isEqual(*d2);
5849 what="Naming arr on nodes differ !";
5856 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5858 MEDFileMesh::clearNonDiscrAttributes();
5859 const DataArrayIdType *tmp=_fam_nodes;
5861 (const_cast<DataArrayIdType *>(tmp))->setName("");
5864 (const_cast<DataArrayIdType *>(tmp))->setName("");
5867 (const_cast<DataArrayIdType *>(tmp))->setName("");
5870 (const_cast<DataArrayIdType *>(tmp))->setName("");
5873 (const_cast<DataArrayIdType *>(tmp))->setName("");
5876 (const_cast<DataArrayIdType *>(tmp))->setName("");
5880 * Returns ids of mesh entities contained in given families of a given dimension.
5881 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5883 * \param [in] fams - the names of the families of interest.
5884 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5885 * returned instead of ids.
5886 * \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
5887 * numbers, if available and required, of mesh entities of the families. The caller
5888 * is to delete this array using decrRef() as it is no more needed.
5889 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5891 DataArrayIdType *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5893 std::vector<mcIdType> famIds(getFamiliesIds(fams));
5894 switch(meshDimRelToMaxExt)
5898 if((const DataArrayIdType *)_fam_nodes)
5900 MCAuto<DataArrayIdType> da;
5902 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5904 da=_fam_nodes->findIdsEqualList(0,0);
5906 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5911 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5916 if((const DataArrayIdType *)_fam_cells)
5918 MCAuto<DataArrayIdType> da;
5920 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5922 da=_fam_cells->findIdsEqualList(0,0);
5924 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5929 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5934 if((const DataArrayIdType *)_fam_faces)
5936 MCAuto<DataArrayIdType> da;
5938 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5940 da=_fam_faces->findIdsEqualList(0,0);
5942 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5947 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5951 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5953 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5957 * Sets the family field of a given relative dimension.
5958 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5959 * the family field is set.
5960 * \param [in] famArr - the array of the family field.
5961 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5962 * \throw If \a famArr has an invalid size.
5963 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5965 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
5967 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5969 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5970 switch(meshDimRelToMaxExt)
5974 mcIdType nbCells(mesh->getNumberOfCells());
5976 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5982 mcIdType nbNodes(mesh->getNumberOfNodes());
5984 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5990 mcIdType nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5992 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5997 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
6004 * Sets the optional numbers of mesh entities of a given dimension.
6005 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6006 * \param [in] renumArr - the array of the numbers.
6007 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6008 * \throw If \a renumArr has an invalid size.
6009 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6011 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
6013 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
6015 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
6016 switch(meshDimRelToMaxExt)
6020 mcIdType nbCells=mesh->getNumberOfCells();
6021 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
6022 _num_cells=renumArr;
6027 mcIdType nbNodes=mesh->getNumberOfNodes();
6028 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
6029 _num_nodes=renumArr;
6034 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6035 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
6036 _num_faces=renumArr;
6040 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
6043 renumArr->incrRef();
6047 * Sets the optional names of mesh entities of a given dimension.
6048 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6049 * \param [in] nameArr - the array of the names.
6050 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6051 * \throw If \a nameArr has an invalid size.
6053 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
6055 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
6057 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
6058 switch(meshDimRelToMaxExt)
6062 mcIdType nbCells=mesh->getNumberOfCells();
6063 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
6064 _names_cells=nameArr;
6069 mcIdType nbNodes=mesh->getNumberOfNodes();
6070 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
6071 _names_nodes=nameArr;
6076 mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
6077 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
6078 _names_faces=nameArr;
6082 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6088 void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
6090 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
6094 * Adds a group of nodes to \a this mesh.
6095 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6096 * The ids should be sorted and different each other (MED file norm).
6098 * \warning this method can alter default "FAMILLE_ZERO" family.
6099 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6101 * \throw If the node coordinates array is not set.
6102 * \throw If \a ids == \c NULL.
6103 * \throw If \a ids->getName() == "".
6104 * \throw If \a ids does not respect the MED file norm.
6105 * \throw If a group with name \a ids->getName() already exists.
6107 void MEDFileStructuredMesh::addNodeGroup(const DataArrayIdType *ids)
6113 * Adds a group of nodes/cells/faces/edges to \a this mesh.
6115 * \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
6116 * The ids should be sorted and different each other (MED file norm).
6118 * \warning this method can alter default "FAMILLE_ZERO" family.
6119 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
6121 * \throw If the node coordinates array is not set.
6122 * \throw If \a ids == \c NULL.
6123 * \throw If \a ids->getName() == "".
6124 * \throw If \a ids does not respect the MED file norm.
6125 * \throw If a group with name \a ids->getName() already exists.
6127 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
6129 DataArrayIdType *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
6130 addGroupUnderground(false,ids,fam);
6135 * Returns the family field for mesh entities of a given dimension.
6136 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6137 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6138 * each mesh entity belongs to. It can be \c NULL.
6139 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6141 const DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
6143 switch(meshDimRelToMaxExt)
6152 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6157 * Returns the family field for mesh entities of a given dimension.
6158 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6159 * \return const DataArrayIdType * - the family field. It is an array of ids of families
6160 * each mesh entity belongs to. It can be \c NULL.
6161 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6163 DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
6165 switch(meshDimRelToMaxExt)
6174 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6179 * Returns the optional numbers of mesh entities of a given dimension.
6180 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6181 * \return const DataArrayIdType * - the array of the entity numbers.
6182 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6183 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6185 const DataArrayIdType *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
6187 switch(meshDimRelToMaxExt)
6196 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6201 * Returns the optional numbers of mesh entities of a given dimension transformed using
6202 * DataArrayIdType::invertArrayN2O2O2N().
6203 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
6204 * \return const DataArrayIdType * - the array of the entity numbers transformed using
6205 * DataArrayIdType::invertArrayN2O2O2N().
6206 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
6207 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
6209 const DataArrayIdType *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
6211 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
6212 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
6213 if(meshDimRelToMaxExt==0)
6215 if((const DataArrayIdType *)_num_cells)
6218 mcIdType maxValue=_num_cells->getMaxValue(pos);
6219 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
6220 return _rev_num_cells;
6223 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
6227 if((const DataArrayIdType *)_num_nodes)
6230 mcIdType maxValue=_num_nodes->getMaxValue(pos);
6231 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
6232 return _rev_num_nodes;
6235 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
6239 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
6241 switch(meshDimRelToMaxExt)
6244 return _names_cells;
6246 return _names_nodes;
6248 return _names_faces;
6250 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
6254 MCAuto<DataArrayIdType> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
6256 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
6260 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
6261 * \return std::vector<int> - a sequence of the relative dimensions: [0].
6263 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
6265 std::vector<int> ret(1);
6270 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
6271 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
6273 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
6275 std::vector<int> ret(2);
6281 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
6283 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
6285 std::vector<int> ret;
6286 const DataArrayIdType *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
6297 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
6299 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
6301 std::vector<int> ret;
6302 const DataArrayIdType *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
6313 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
6315 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6317 std::vector<int> ret;
6318 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6329 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6331 bool MEDFileStructuredMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
6333 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6337 void MEDFileStructuredMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
6339 DataArrayIdType *arr=_fam_nodes;
6341 arr->changeValue(oldId,newId);
6344 arr->changeValue(oldId,newId);
6347 arr->changeValue(oldId,newId);
6350 std::list< MCAuto<DataArrayIdType> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6352 std::list< MCAuto<DataArrayIdType> > ret;
6353 const DataArrayIdType *da(_fam_nodes);
6355 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6358 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6361 { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
6365 void MEDFileStructuredMesh::deepCpyAttributes()
6367 if((const DataArrayIdType*)_fam_nodes)
6368 _fam_nodes=_fam_nodes->deepCopy();
6369 if((const DataArrayIdType*)_num_nodes)
6370 _num_nodes=_num_nodes->deepCopy();
6371 if((const DataArrayAsciiChar*)_names_nodes)
6372 _names_nodes=_names_nodes->deepCopy();
6373 if((const DataArrayIdType*)_fam_cells)
6374 _fam_cells=_fam_cells->deepCopy();
6375 if((const DataArrayIdType*)_num_cells)
6376 _num_cells=_num_cells->deepCopy();
6377 if((const DataArrayAsciiChar*)_names_cells)
6378 _names_cells=_names_cells->deepCopy();
6379 if((const DataArrayIdType*)_fam_faces)
6380 _fam_faces=_fam_faces->deepCopy();
6381 if((const DataArrayIdType*)_num_faces)
6382 _num_faces=_num_faces->deepCopy();
6383 if((const DataArrayAsciiChar*)_names_faces)
6384 _names_faces=_names_faces->deepCopy();
6385 if((const DataArrayIdType*)_rev_num_nodes)
6386 _rev_num_nodes=_rev_num_nodes->deepCopy();
6387 if((const DataArrayIdType*)_rev_num_cells)
6388 _rev_num_cells=_rev_num_cells->deepCopy();
6392 * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
6394 * \return a pointer to cartesian mesh that need to be managed by the caller.
6395 * \warning the returned pointer has to be managed by the caller.
6399 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6400 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6401 * \param [in] renum - it must be \c false.
6402 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6403 * delete using decrRef() as it is no more needed.
6405 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6409 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6410 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6411 switch(meshDimRelToMax)
6417 return const_cast<MEDCouplingStructuredMesh *>(m);
6422 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6423 buildMinusOneImplicitPartIfNeeded();
6424 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6430 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6435 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
6436 * To include nodes, call getFamsNonEmptyLevelsExt() method.
6437 * \param [in] fams - the name of the family of interest.
6438 * \return std::vector<int> - a sequence of the relative dimensions.
6440 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6442 std::vector<mcIdType> lvls;
6443 std::vector<mcIdType> famIds(getFamiliesIds(fams));
6444 const DataArrayIdType *famCells(_fam_cells),*famFaces(_fam_faces);
6445 if(famCells && famCells->presenceOfValue(famIds))
6447 if(famFaces && famFaces->presenceOfValue(famIds))
6453 * Returns all relative mesh levels (including nodes) where given families are defined.
6454 * \param [in] fams - the names of the families of interest.
6455 * \return std::vector<int> - a sequence of the relative dimensions.
6457 std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6459 std::vector<mcIdType> lvls(getFamsNonEmptyLevels(fams));
6460 std::vector<mcIdType> famIds(getFamiliesIds(fams));
6461 const DataArrayIdType *famNodes(_fam_nodes);
6462 if(famNodes && famNodes->presenceOfValue(famIds))
6468 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6469 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6470 * \return mcIdType - the number of entities.
6471 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6473 mcIdType MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6475 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6477 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6478 switch(meshDimRelToMaxExt)
6481 return cmesh->getNumberOfCells();
6483 return cmesh->getNumberOfNodes();
6485 return cmesh->getNumberOfCellsOfSubLevelMesh();
6487 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6491 mcIdType MEDFileStructuredMesh::getNumberOfNodes() const
6493 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6495 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6496 return cmesh->getNumberOfNodes();
6499 mcIdType MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6501 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6503 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6504 switch(meshDimRelToMaxExt)
6507 return cmesh->getNumberOfCells();
6509 return cmesh->getNumberOfCellsOfSubLevelMesh();
6511 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6515 bool MEDFileStructuredMesh::hasImplicitPart() const
6521 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6523 mcIdType MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6525 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6526 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6529 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6530 if(cm.getReverseExtrudedType()!=gt)
6531 throw INTERP_KERNEL::Exception(MSG);
6532 buildImplicitPart();
6533 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6537 if(gt!=zeFaceMesh->getCellModelEnum())
6538 throw INTERP_KERNEL::Exception(MSG);
6539 return zeFaceMesh->getNumberOfCells();
6543 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6545 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6547 buildImplicitPart();
6550 void MEDFileStructuredMesh::buildImplicitPart() const
6552 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6554 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6555 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6558 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6560 _faces_if_necessary=0;
6564 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6565 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6567 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6569 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6572 return _faces_if_necessary;
6575 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6577 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6579 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6580 switch(meshDimRelToMax)
6584 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6589 int mdim(cmesh->getMeshDimension());
6591 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6592 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6596 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6600 mcIdType MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6602 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6605 return getNumberOfCellsAtLevel(0);
6608 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6610 if(st.getNumberOfItems()!=1)
6611 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 !");
6612 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6613 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6614 if(getNumberOfNodes()!=(mcIdType)nodesFetched.size())
6615 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6616 if(st[0].getPflName().empty())
6618 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6621 const DataArrayIdType *arr(globs->getProfile(st[0].getPflName()));
6622 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6623 mcIdType sz(ToIdType(nodesFetched.size()));
6624 for(const mcIdType *work=arr->begin();work!=arr->end();work++)
6626 std::vector<mcIdType> conn;
6627 cmesh->getNodeIdsOfCell(*work,conn);
6628 for(std::vector<mcIdType>::const_iterator it=conn.begin();it!=conn.end();it++)
6629 if(*it>=0 && *it<sz)
6630 nodesFetched[*it]=true;
6632 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6636 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6638 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6642 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6643 MCAuto<DataArrayIdType>& famCells, MCAuto<DataArrayIdType>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6645 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6646 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6647 mcIdType nbOfElt(0);
6648 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6651 if(!mrs || mrs->isCellFamilyFieldReading())
6653 MCAuto<DataArrayMedInt> miFamCells=DataArrayMedInt::New();
6654 miFamCells->alloc(nbOfElt,1);
6655 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miFamCells->getPointer()));
6656 famCells = FromMedIntArray<mcIdType>( miFamCells );
6659 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6662 if(!mrs || mrs->isCellNumFieldReading())
6664 MCAuto<DataArrayMedInt> miNumCells=DataArrayMedInt::New();
6665 miNumCells->alloc(nbOfElt,1);
6666 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miNumCells->getPointer()));
6667 numCells = FromMedIntArray<mcIdType>( miNumCells );
6670 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6673 if(!mrs || mrs->isCellNameFieldReading())
6675 namesCells=DataArrayAsciiChar::New();
6676 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6677 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6678 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6683 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6685 setName(strm->getName());
6686 setDescription(strm->getDescription());
6687 setUnivName(strm->getUnivName());
6688 setIteration(strm->getIteration());
6689 setOrder(strm->getOrder());
6690 setTimeValue(strm->getTime());
6691 setTimeUnit(strm->getTimeUnit());
6692 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6693 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6694 mcIdType nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6697 if(!mrs || mrs->isNodeFamilyFieldReading())
6699 mcIdType nbNodes(getNumberOfNodes());
6701 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6702 MCAuto<DataArrayMedInt> miFamNodes=DataArrayMedInt::New();
6703 miFamNodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6704 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...
6705 miFamNodes->fillWithZero();
6706 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miFamNodes->getPointer()));
6707 _fam_nodes = FromMedIntArray<mcIdType>( miFamNodes );
6710 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6713 if(!mrs || mrs->isNodeNumFieldReading())
6715 MCAuto<DataArrayMedInt> miNumNodes=DataArrayMedInt::New();
6716 miNumNodes->alloc(nbOfElt,1);
6717 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miNumNodes->getPointer()));
6718 _num_nodes = FromMedIntArray<mcIdType>( miNumNodes );
6721 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6724 if(!mrs || mrs->isNodeNameFieldReading())
6726 _names_nodes=DataArrayAsciiChar::New();
6727 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6728 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6729 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6732 int meshDim(getStructuredMesh()->getMeshDimension());
6733 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6735 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6738 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6740 int meshDim(getStructuredMesh()->getMeshDimension());
6741 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6743 if((const DataArrayIdType *)_fam_cells)
6744 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_fam_cells->getNumberOfTuples()),ToMedIntArray(_fam_cells)->getConstPointer()));
6745 if((const DataArrayIdType *)_fam_faces)
6746 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_fam_faces->getNumberOfTuples()),ToMedIntArray(_fam_faces)->getConstPointer()));
6747 if((const DataArrayIdType *)_fam_nodes)
6748 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_fam_nodes->getNumberOfTuples()),ToMedIntArray(_fam_nodes)->getConstPointer()));
6749 if((const DataArrayIdType *)_num_cells)
6750 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_num_cells->getNumberOfTuples()),ToMedIntArray(_num_cells)->getConstPointer()));
6751 if((const DataArrayIdType *)_num_faces)
6752 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_num_faces->getNumberOfTuples()),ToMedIntArray(_num_faces)->getConstPointer()));
6753 if((const DataArrayIdType *)_num_nodes)
6754 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_num_nodes->getNumberOfTuples()),ToMedIntArray(_num_nodes)->getConstPointer()));
6755 if((const DataArrayAsciiChar *)_names_cells)
6757 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6759 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6760 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6761 throw INTERP_KERNEL::Exception(oss.str().c_str());
6763 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_names_cells->getNumberOfTuples()),_names_cells->getConstPointer()));
6765 if((const DataArrayAsciiChar *)_names_faces)
6767 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6769 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6770 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6771 throw INTERP_KERNEL::Exception(oss.str().c_str());
6773 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_names_faces->getNumberOfTuples()),_names_faces->getConstPointer()));
6775 if((const DataArrayAsciiChar *)_names_nodes)
6777 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6779 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6780 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6781 throw INTERP_KERNEL::Exception(oss.str().c_str());
6783 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_names_nodes->getNumberOfTuples()),_names_nodes->getConstPointer()));
6786 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6790 * Returns an empty instance of MEDFileCMesh.
6791 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6792 * mesh using decrRef() as it is no more needed.
6794 MEDFileCMesh *MEDFileCMesh::New()
6796 return new MEDFileCMesh;
6800 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6801 * file. The first mesh in the file is loaded.
6802 * \param [in] fileName - the name of MED file to read.
6803 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6804 * mesh using decrRef() as it is no more needed.
6805 * \throw If the file is not readable.
6806 * \throw If there is no meshes in the file.
6807 * \throw If the mesh in the file is not a Cartesian one.
6809 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6811 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6812 return New(fid,mrs);
6815 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6817 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6821 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6822 * file. The mesh to load is specified by its name and numbers of a time step and an
6824 * \param [in] fileName - the name of MED file to read.
6825 * \param [in] mName - the name of the mesh to read.
6826 * \param [in] dt - the number of a time step.
6827 * \param [in] it - the number of an iteration.
6828 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6829 * mesh using decrRef() as it is no more needed.
6830 * \throw If the file is not readable.
6831 * \throw If there is no mesh with given attributes in the file.
6832 * \throw If the mesh in the file is not a Cartesian one.
6834 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6836 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6837 return New(fid,mName,dt,it,mrs);
6840 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6842 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6845 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6847 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6850 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6852 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6853 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6858 * Returns the dimension on cells in \a this mesh.
6859 * \return int - the mesh dimension.
6860 * \throw If there are no cells in this mesh.
6862 int MEDFileCMesh::getMeshDimension() const
6864 if(!((const MEDCouplingCMesh*)_cmesh))
6865 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6866 return _cmesh->getMeshDimension();
6870 * Returns the dimension on nodes in \a this mesh.
6871 * \return int - the space dimension.
6872 * \throw If there are no cells in this mesh.
6874 int MEDFileCMesh::getSpaceDimension() const
6876 if(!((const MEDCouplingCMesh*)_cmesh))
6877 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6878 return _cmesh->getSpaceDimension();
6882 * Returns a string describing \a this mesh.
6883 * \return std::string - the mesh information string.
6885 std::string MEDFileCMesh::simpleRepr() const
6887 return MEDFileStructuredMesh::simpleRepr();
6891 * Returns a full textual description of \a this mesh.
6892 * \return std::string - the string holding the mesh description.
6894 std::string MEDFileCMesh::advancedRepr() const
6896 return simpleRepr();
6899 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6901 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6905 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6907 return new MEDFileCMesh;
6910 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6912 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6913 ret->deepCpyEquivalences(*this);
6914 if((const MEDCouplingCMesh*)_cmesh)
6915 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6916 ret->deepCpyAttributes();
6921 * Checks if \a this and another mesh are equal.
6922 * \param [in] other - the mesh to compare with.
6923 * \param [in] eps - a precision used to compare real values.
6924 * \param [in,out] what - the string returning description of unequal data.
6925 * \return bool - \c true if the meshes are equal, \c false, else.
6927 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6929 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6931 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6934 what="Mesh types differ ! This is cartesian and other is NOT !";
6937 clearNonDiscrAttributes();
6938 otherC->clearNonDiscrAttributes();
6939 const MEDCouplingCMesh *coo1=_cmesh;
6940 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6941 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6943 what="Mismatch of cartesian meshes ! One is defined and not other !";
6948 bool ret=coo1->isEqual(coo2,eps);
6951 what="cartesian meshes differ !";
6959 * Clears redundant attributes of incorporated data arrays.
6961 void MEDFileCMesh::clearNonDiscrAttributes() const
6963 MEDFileStructuredMesh::clearNonDiscrAttributes();
6964 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6967 MEDFileCMesh::MEDFileCMesh()
6971 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6974 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6976 catch(INTERP_KERNEL::Exception& e)
6981 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6983 MEDCoupling::MEDCouplingMeshType meshType;
6986 MEDCoupling::MEDCouplingAxisType axType;
6987 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6988 if(meshType!=CARTESIAN)
6990 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6991 throw INTERP_KERNEL::Exception(oss.str().c_str());
6993 MEDFileCMeshL2 loaderl2;
6994 loaderl2.loadAll(fid,mid,mName,dt,it);
6995 setAxisType(axType);
6996 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6999 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7003 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
7004 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
7006 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
7008 synchronizeTinyInfoOnLeaves();
7012 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
7014 synchronizeTinyInfoOnLeaves();
7019 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
7020 * \param [in] m - the new MEDCouplingCMesh to refer to.
7021 * \throw If the name or the description of \a this mesh and \a m are not empty and are
7024 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
7026 dealWithTinyInfo(m);
7032 MEDFileMesh *MEDFileCMesh::cartesianize() const
7034 if(getAxisType()==AX_CART)
7037 return const_cast<MEDFileCMesh *>(this);
7041 const MEDCouplingCMesh *cmesh(getMesh());
7043 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7044 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
7045 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
7046 clmesh->setCoords(coords);
7047 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
7048 ret->MEDFileStructuredMesh::operator=(*this);
7049 ret->setMesh(clmesh);
7050 ret->setAxisType(AX_CART);
7055 void MEDFileCMesh::writeMeshLL(med_idt fid) const
7057 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7058 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7059 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7060 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7061 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7062 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7063 int spaceDim(_cmesh->getSpaceDimension());
7064 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7065 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7066 for(int i=0;i<spaceDim;i++)
7068 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
7070 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7071 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
7072 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
7074 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7076 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7077 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
7078 for(int i=0;i<spaceDim;i++)
7080 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
7081 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,ToMedInt(da->getNumberOfTuples()),da->getConstPointer()));
7084 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7085 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7088 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
7090 const MEDCouplingCMesh *cmesh=_cmesh;
7093 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
7094 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
7095 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
7096 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
7099 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
7101 return new MEDFileCurveLinearMesh;
7104 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
7106 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
7109 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
7111 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7112 return New(fid,mrs);
7115 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7117 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7118 return New(fid,mName,dt,it,mrs);
7121 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7123 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
7126 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
7128 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
7131 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
7133 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
7134 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
7138 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
7140 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7144 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
7146 return new MEDFileCurveLinearMesh;
7149 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
7151 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7152 ret->deepCpyEquivalences(*this);
7153 if((const MEDCouplingCurveLinearMesh*)_clmesh)
7154 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
7155 ret->deepCpyAttributes();
7159 int MEDFileCurveLinearMesh::getMeshDimension() const
7161 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7162 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get mesh dimension because no mesh set !");
7163 return _clmesh->getMeshDimension();
7166 int MEDFileCurveLinearMesh::getSpaceDimension() const
7168 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
7169 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get space dimension because no mesh set !");
7170 return _clmesh->getSpaceDimension();
7173 std::string MEDFileCurveLinearMesh::simpleRepr() const
7175 return MEDFileStructuredMesh::simpleRepr();
7178 std::string MEDFileCurveLinearMesh::advancedRepr() const
7180 return simpleRepr();
7183 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
7185 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
7187 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
7190 what="Mesh types differ ! This is curve linear and other is NOT !";
7193 clearNonDiscrAttributes();
7194 otherC->clearNonDiscrAttributes();
7195 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
7196 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
7197 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
7199 what="Mismatch of curve linear meshes ! One is defined and not other !";
7204 bool ret=coo1->isEqual(coo2,eps);
7207 what="curve linear meshes differ !";
7214 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
7216 MEDFileStructuredMesh::clearNonDiscrAttributes();
7217 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
7220 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
7222 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
7225 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
7226 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
7227 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
7228 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
7231 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
7233 synchronizeTinyInfoOnLeaves();
7237 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
7239 dealWithTinyInfo(m);
7245 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
7247 if(getAxisType()==AX_CART)
7250 return const_cast<MEDFileCurveLinearMesh *>(this);
7254 const MEDCouplingCurveLinearMesh *mesh(getMesh());
7256 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
7257 const DataArrayDouble *coords(mesh->getCoords());
7259 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
7260 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
7261 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
7262 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
7263 mesh2->setCoords(coordsCart);
7264 ret->setMesh(mesh2);
7265 ret->setAxisType(AX_CART);
7270 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
7272 synchronizeTinyInfoOnLeaves();
7276 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
7280 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7283 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
7285 catch(INTERP_KERNEL::Exception& e)
7290 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
7292 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
7293 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
7294 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
7295 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
7296 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
7297 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
7298 int spaceDim=_clmesh->getSpaceDimension();
7299 int meshDim=_clmesh->getMeshDimension();
7300 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7301 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
7302 const DataArrayDouble *coords=_clmesh->getCoords();
7304 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
7305 for(int i=0;i<spaceDim;i++)
7307 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
7309 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
7310 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
7311 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
7313 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
7315 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
7316 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
7317 std::vector<mcIdType> nodeGridSt=_clmesh->getNodeGridStructure();
7318 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,ToMedIntArray(nodeGridSt)->getConstPointer()));
7320 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,ToMedInt(coords->getNumberOfTuples()),coords->begin()));
7322 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
7323 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
7326 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
7328 MEDCoupling::MEDCouplingMeshType meshType;
7331 MEDCoupling::MEDCouplingAxisType axType;
7332 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
7333 setAxisType(axType);
7334 if(meshType!=CURVE_LINEAR)
7336 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
7337 throw INTERP_KERNEL::Exception(oss.str().c_str());
7339 MEDFileCLMeshL2 loaderl2;
7340 loaderl2.loadAll(fid,mid,mName,dt,it);
7341 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7344 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7347 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7349 return new MEDFileMeshMultiTS;
7352 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7354 return new MEDFileMeshMultiTS(fid);
7357 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7359 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7363 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7365 return new MEDFileMeshMultiTS(fid,mName);
7368 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7370 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7371 return New(fid,mName);
7374 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7376 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7377 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7379 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7380 if((const MEDFileMesh *)*it)
7381 meshOneTs[i]=(*it)->deepCopy();
7382 ret->_mesh_one_ts=meshOneTs;
7386 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7388 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7391 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7393 std::vector<const BigMemoryObject *> ret;
7394 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7395 ret.push_back((const MEDFileMesh *)*it);
7399 std::string MEDFileMeshMultiTS::getName() const
7401 if(_mesh_one_ts.empty())
7402 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7403 return _mesh_one_ts[0]->getName();
7406 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7408 std::string oldName(getName());
7409 std::vector< std::pair<std::string,std::string> > v(1);
7410 v[0].first=oldName; v[0].second=newMeshName;
7414 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7417 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7419 MEDFileMesh *cur(*it);
7421 ret=cur->changeNames(modifTab) || ret;
7426 void MEDFileMeshMultiTS::cartesianizeMe()
7428 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7430 MEDFileMesh *cur(*it);
7433 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7439 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7441 if(_mesh_one_ts.empty())
7442 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7443 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7446 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7449 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7450 _mesh_one_ts.resize(1);
7451 mesh1TimeStep->incrRef();
7452 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7453 _mesh_one_ts[0]=mesh1TimeStep;
7456 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7458 if ( MEDFileMesh* m = getOneTimeStep() )
7459 return m->getJoints();
7464 * \brief Set Joints that are common to all time-stamps
7466 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7468 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7470 (*it)->setJoints( joints );
7474 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7476 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7477 if((*it).isNotNull())
7478 if((*it)->presenceOfStructureElements())
7483 void MEDFileMeshMultiTS::killStructureElements()
7485 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7486 if((*it).isNotNull())
7487 (*it)->killStructureElements();
7490 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7492 MEDFileJoints *joints(getJoints());
7493 bool jointsWritten(false);
7495 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7497 if ( jointsWritten )
7498 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7500 jointsWritten = true;
7502 (*it)->copyOptionsFrom(*this);
7503 (*it)->writeLL(fid);
7506 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7509 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7511 MEDFileJoints *joints(0);
7512 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7514 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7515 joints = getOneTimeStep()->getJoints();
7517 _mesh_one_ts.clear(); //for the moment to be improved
7518 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7521 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7525 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7528 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7531 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7532 throw INTERP_KERNEL::Exception(oss.str().c_str());
7535 MEDCoupling::MEDCouplingMeshType meshType;
7537 MEDCoupling::MEDCouplingAxisType dummy3;
7538 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7539 loadFromFile(fid,ms.front());
7541 catch(INTERP_KERNEL::Exception& e)
7546 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7549 loadFromFile(fid,mName);
7551 catch(INTERP_KERNEL::Exception& e)
7556 MEDFileMeshes *MEDFileMeshes::New()
7558 return new MEDFileMeshes;
7561 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7563 return new MEDFileMeshes(fid);
7566 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7568 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7572 void MEDFileMeshes::writeLL(med_idt fid) const
7574 checkConsistencyLight();
7575 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7577 (*it)->copyOptionsFrom(*this);
7578 (*it)->writeLL(fid);
7582 // MEDFileMeshes::writ checkConsistencyLight();
7584 int MEDFileMeshes::getNumberOfMeshes() const
7586 return (int)_meshes.size();
7589 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7591 return new MEDFileMeshesIterator(this);
7594 /** Return a borrowed reference (caller is not responsible) */
7595 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7597 if(i<0 || i>=(int)_meshes.size())
7599 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7600 throw INTERP_KERNEL::Exception(oss.str().c_str());
7602 return _meshes[i]->getOneTimeStep();
7605 /** Return a borrowed reference (caller is not responsible) */
7606 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7608 std::vector<std::string> ms=getMeshesNames();
7609 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7612 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7613 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7614 throw INTERP_KERNEL::Exception(oss.str().c_str());
7616 return getMeshAtPos((int)std::distance(ms.begin(),it));
7619 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7621 std::vector<std::string> ret(_meshes.size());
7623 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7625 const MEDFileMeshMultiTS *f=(*it);
7628 ret[i]=f->getName();
7632 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7633 throw INTERP_KERNEL::Exception(oss.str().c_str());
7639 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7642 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7644 MEDFileMeshMultiTS *cur(*it);
7646 ret=cur->changeNames(modifTab) || ret;
7651 void MEDFileMeshes::cartesianizeMe()
7653 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7655 MEDFileMeshMultiTS *cur(*it);
7657 cur->cartesianizeMe();
7661 void MEDFileMeshes::resize(int newSize)
7663 _meshes.resize(newSize);
7666 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7669 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7670 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7671 elt->setOneTimeStep(mesh);
7672 _meshes.push_back(elt);
7675 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7678 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7679 if(i>=(int)_meshes.size())
7680 _meshes.resize(i+1);
7681 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7682 elt->setOneTimeStep(mesh);
7686 void MEDFileMeshes::destroyMeshAtPos(int i)
7688 if(i<0 || i>=(int)_meshes.size())
7690 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7691 throw INTERP_KERNEL::Exception(oss.str().c_str());
7693 _meshes.erase(_meshes.begin()+i);
7696 void MEDFileMeshes::loadFromFile(med_idt fid)
7698 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7700 _meshes.resize(ms.size());
7701 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7702 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7705 MEDFileMeshes::MEDFileMeshes()
7709 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7714 catch(INTERP_KERNEL::Exception& /*e*/)
7718 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7720 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7722 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7723 if((const MEDFileMeshMultiTS *)*it)
7724 meshes[i]=(*it)->deepCopy();
7725 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7726 ret->_meshes=meshes;
7730 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7732 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7735 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7737 std::vector<const BigMemoryObject *> ret;
7738 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7739 ret.push_back((const MEDFileMeshMultiTS *)*it);
7743 std::string MEDFileMeshes::simpleRepr() const
7745 std::ostringstream oss;
7746 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7747 simpleReprWithoutHeader(oss);
7751 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7753 int nbOfMeshes=getNumberOfMeshes();
7754 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7755 std::vector<std::string> mns=getMeshesNames();
7756 for(int i=0;i<nbOfMeshes;i++)
7757 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7760 void MEDFileMeshes::checkConsistencyLight() const
7762 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7764 std::set<std::string> s;
7765 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7767 const MEDFileMeshMultiTS *elt=(*it);
7770 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7771 throw INTERP_KERNEL::Exception(oss.str().c_str());
7773 std::size_t sz=s.size();
7774 s.insert(std::string((*it)->getName()));
7777 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7778 throw INTERP_KERNEL::Exception(oss.str().c_str());
7783 bool MEDFileMeshes::presenceOfStructureElements() const
7785 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7786 if((*it).isNotNull())
7787 if((*it)->presenceOfStructureElements())
7792 void MEDFileMeshes::killStructureElements()
7794 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7795 if((*it).isNotNull())
7796 (*it)->killStructureElements();
7799 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7804 _nb_iter=ms->getNumberOfMeshes();
7808 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7812 MEDFileMesh *MEDFileMeshesIterator::nextt()
7814 if(_iter_id<_nb_iter)
7816 MEDFileMeshes *ms(_ms);
7818 return ms->getMeshAtPos(_iter_id++);
7826 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7828 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7829 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7831 if(geoType==MED_NO_GEOTYPE)
7832 return INTERP_KERNEL::NORM_ERROR;
7833 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7834 throw INTERP_KERNEL::Exception(oss.str());
7836 return typmai2[std::distance(typmai,pos)];
7839 med_geometry_type MEDFileMesh::ConvertToMEDFileGeoType(INTERP_KERNEL::NormalizedCellType geoType)
7841 INTERP_KERNEL::NormalizedCellType *pos(std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,geoType));
7842 if(pos==typmai2+MED_N_CELL_FIXED_GEO)
7844 THROW_IK_EXCEPTION("MEDFileMesh::ConvertToMEDFileGeoType : no entry for " << geoType);
7846 return typmai[std::distance(typmai2,pos)];
7849 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7857 case MED_NODE_ELEMENT:
7861 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7862 throw INTERP_KERNEL::Exception(oss.str());