1 // Copyright (C) 2007-2016 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"
32 #include "InterpKernelAutoPtr.hxx"
37 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
38 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
39 extern med_geometry_type typmai3[34];
41 using namespace MEDCoupling;
43 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
45 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
47 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
51 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
53 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
54 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
56 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
57 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
58 ret+=(*it2).capacity();
60 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
61 ret+=(*it).first.capacity()+sizeof(int);
65 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
67 std::vector<const BigMemoryObject *> ret(1);
68 ret[0]=(const MEDFileEquivalences *)_equiv;
73 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
74 * file. The first mesh in the file is loaded.
75 * \param [in] fileName - the name of MED file to read.
76 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
77 * mesh using decrRef() as it is no more needed.
78 * \throw If the file is not readable.
79 * \throw If there is no meshes in the file.
80 * \throw If the mesh in the file is of a not supported type.
82 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
84 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
88 MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
90 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
93 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
94 throw INTERP_KERNEL::Exception(oss.str().c_str());
96 MEDCoupling::MEDCouplingMeshType meshType;
99 MEDCoupling::MEDCouplingAxisType dummy3;
100 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
101 MCAuto<MEDFileMesh> ret;
106 ret=MEDFileUMesh::New();
111 ret=MEDFileCMesh::New();
116 ret=MEDFileCurveLinearMesh::New();
121 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
122 throw INTERP_KERNEL::Exception(oss.str().c_str());
125 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
130 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
131 * file. The mesh to load is specified by its name and numbers of a time step and an
133 * \param [in] fileName - the name of MED file to read.
134 * \param [in] mName - the name of the mesh to read.
135 * \param [in] dt - the number of a time step.
136 * \param [in] it - the number of an iteration.
137 * \param [in] joints - the sub-domain joints to use instead of those that can be read
138 * from the MED file. Usually this joints are those just read by another iteration
139 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
140 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
141 * mesh using decrRef() as it is no more needed.
142 * \throw If the file is not readable.
143 * \throw If there is no mesh with given attributes in the file.
144 * \throw If the mesh in the file is of a not supported type.
146 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
148 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
149 return New(fid,mName,dt,it,mrs,joints);
152 MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
154 MEDCoupling::MEDCouplingMeshType meshType;
157 MEDCoupling::MEDCouplingAxisType dummy3;
158 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
159 MCAuto<MEDFileMesh> ret;
164 ret=MEDFileUMesh::New();
169 ret=MEDFileCMesh::New();
174 ret=MEDFileCurveLinearMesh::New();
179 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
180 throw INTERP_KERNEL::Exception(oss.str().c_str());
183 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
188 * Writes \a this mesh into an open MED file specified by its descriptor.
189 * \param [in] fid - the MED file descriptor.
190 * \throw If the mesh name is not set.
191 * \throw If the file is open for reading only.
192 * \throw If the writing mode == 1 and the same data is present in an existing file.
194 void MEDFileMesh::writeLL(med_idt fid) const
197 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
199 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
202 const MEDFileEquivalences *eqs(_equiv);
208 * Checks if \a this and another mesh are equal.
209 * \param [in] other - the mesh to compare with.
210 * \param [in] eps - a precision used to compare real values.
211 * \param [in,out] what - the string returning description of unequal data.
212 * \return bool - \c true if the meshes are equal, \c false, else.
214 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
216 if(_order!=other->_order)
218 what="Orders differ !";
221 if(_iteration!=other->_iteration)
223 what="Iterations differ !";
226 if(fabs(_time-other->_time)>eps)
228 what="Time values differ !";
231 if(_dt_unit!=other->_dt_unit)
233 what="Time units differ !";
236 if(_name!=other->_name)
238 what="Names differ !";
241 //univ_name has been ignored -> not a bug because it is a mutable attribute
242 if(_desc_name!=other->_desc_name)
244 what="Description names differ !";
247 if(!areGrpsEqual(other,what))
249 if(!areFamsEqual(other,what))
251 if(!areEquivalencesEqual(other,what))
256 void MEDFileMesh::setName(const std::string& name)
262 * Clears redundant attributes of incorporated data arrays.
264 void MEDFileMesh::clearNonDiscrAttributes() const
269 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
271 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
273 if((*it).first==_name)
283 * Copies data on groups and families from another mesh.
284 * \param [in] other - the mesh to copy the data from.
286 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
288 _groups=other._groups;
289 _families=other._families;
294 * This method clear all the groups in the map.
295 * So this method does not operate at all on arrays.
296 * So this method can lead to orphan families.
298 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
300 void MEDFileMesh::clearGrpMap()
306 * This method clear all the families in the map.
307 * So this method does not operate at all on arrays.
308 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
310 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
312 void MEDFileMesh::clearFamMap()
318 * This method clear all the families and groups in the map.
319 * So this method does not operate at all on arrays.
320 * As all groups and families entry will be removed after
321 * 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.
323 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
325 void MEDFileMesh::clearFamGrpMaps()
332 * Returns names of families constituting a group.
333 * \param [in] name - the name of the group of interest.
334 * \return std::vector<std::string> - a sequence of names of the families.
335 * \throw If the name of a nonexistent group is specified.
337 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
339 std::string oname(name);
340 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
341 if(it==_groups.end())
343 std::vector<std::string> grps=getGroupsNames();
344 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
345 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
346 throw INTERP_KERNEL::Exception(oss.str().c_str());
352 * Returns names of families constituting some groups.
353 * \param [in] grps - a sequence of names of groups of interest.
354 * \return std::vector<std::string> - a sequence of names of the families.
355 * \throw If a name of a nonexistent group is present in \a grps.
357 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
359 std::set<std::string> fams;
360 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
362 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
363 if(it2==_groups.end())
365 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
366 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
367 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
368 throw INTERP_KERNEL::Exception(oss.str().c_str());
370 fams.insert((*it2).second.begin(),(*it2).second.end());
372 std::vector<std::string> fams2(fams.begin(),fams.end());
377 * Returns ids of families constituting a group.
378 * \param [in] name - the name of the group of interest.
379 * \return std::vector<int> - sequence of ids of the families.
380 * \throw If the name of a nonexistent group is specified.
382 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
384 std::string oname(name);
385 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
386 std::vector<std::string> grps=getGroupsNames();
387 if(it==_groups.end())
389 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
390 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
391 throw INTERP_KERNEL::Exception(oss.str().c_str());
393 return getFamiliesIds((*it).second);
397 * Sets names of families constituting a group. If data on families of this group is
398 * already present, it is overwritten. Every family in \a fams is checked, and if a
399 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
400 * \param [in] name - the name of the group of interest.
401 * \param [in] fams - a sequence of names of families constituting the group.
403 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
405 std::string oname(name);
407 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
409 std::map<std::string,int>::iterator it2=_families.find(*it1);
410 if(it2==_families.end())
416 * Sets families constituting a group. The families are specified by their ids.
417 * If a family name is not found by its id, an exception is thrown.
418 * If several families have same id, the first one in lexical order is taken.
419 * \param [in] name - the name of the group of interest.
420 * \param [in] famIds - a sequence of ids of families constituting the group.
421 * \throw If a family name is not found by its id.
423 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
425 std::string oname(name);
426 std::vector<std::string> fams(famIds.size());
428 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
430 std::string name2=getFamilyNameGivenId(*it1);
437 * Returns names of groups including a given family.
438 * \param [in] name - the name of the family of interest.
439 * \return std::vector<std::string> - a sequence of names of groups including the family.
441 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
443 std::vector<std::string> ret;
444 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
446 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
449 ret.push_back((*it1).first);
457 * Adds an existing family to groups.
458 * \param [in] famName - a name of family to add to \a grps.
459 * \param [in] grps - a sequence of group names to add the family in.
460 * \throw If a family named \a famName not yet exists.
462 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
464 std::string fName(famName);
465 const std::map<std::string,int>::const_iterator it=_families.find(fName);
466 if(it==_families.end())
468 std::vector<std::string> fams=getFamiliesNames();
469 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
470 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
471 throw INTERP_KERNEL::Exception(oss.str().c_str());
473 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
475 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
476 if(it2!=_groups.end())
477 (*it2).second.push_back(fName);
480 std::vector<std::string> grps2(1,fName);
487 * Returns names of all groups of \a this mesh.
488 * \return std::vector<std::string> - a sequence of group names.
490 std::vector<std::string> MEDFileMesh::getGroupsNames() const
492 std::vector<std::string> ret(_groups.size());
494 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
500 * Returns names of all families of \a this mesh.
501 * \return std::vector<std::string> - a sequence of family names.
503 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
505 std::vector<std::string> ret(_families.size());
507 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
513 * Returns names of all families of \a this mesh but like they would be in file.
514 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
515 * 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 !
516 * For your information internaly in memory such families are renamed to have a nicer API.
518 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
520 std::vector<std::string> ret(getFamiliesNames());
521 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
526 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
527 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
528 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
531 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
533 std::vector<std::string> ret;
534 std::vector<std::string> allGrps(getGroupsNames());
535 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
537 std::vector<int> levs(getGrpNonEmptyLevelsExt((*it)));
538 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
545 * Returns all relative mesh levels (including nodes) where a given group is defined.
546 * \param [in] grp - the name of the group of interest.
547 * \return std::vector<int> - a sequence of the relative dimensions.
549 std::vector<int> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
551 std::vector<std::string> fams(getFamiliesOnGroup(grp));
552 return getFamsNonEmptyLevelsExt(fams);
556 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
557 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
558 * \param [in] grps - a sequence of names of the groups of interest.
559 * \return std::vector<int> - a sequence of the relative dimensions.
561 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
563 std::vector<std::string> fams(getFamiliesOnGroups(grps));
564 return getFamsNonEmptyLevels(fams);
568 * Returns all relative mesh levels (including nodes) where given groups are defined.
569 * \param [in] grps - a sequence of names of the groups of interest.
570 * \return std::vector<int> - a sequence of the relative dimensions.
572 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
574 std::vector<std::string> fams(getFamiliesOnGroups(grps));
575 return getFamsNonEmptyLevelsExt(fams);
579 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
580 * To include nodes, call getGrpNonEmptyLevelsExt() method.
581 * \param [in] grp - the name of the group of interest.
582 * \return std::vector<int> - a sequence of the relative dimensions.
584 std::vector<int> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
586 std::vector<std::string> fams(getFamiliesOnGroup(grp));
587 return getFamsNonEmptyLevels(fams);
591 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
592 * To include nodes, call getFamNonEmptyLevelsExt() method.
593 * \param [in] fam - the name of the family of interest.
594 * \return std::vector<int> - a sequence of the relative dimensions.
596 std::vector<int> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
598 std::vector<std::string> fams(1,std::string(fam));
599 return getFamsNonEmptyLevels(fams);
603 * Returns all relative mesh levels (including nodes) where a given family is defined.
604 * \param [in] fam - the name of the family of interest.
605 * \return std::vector<int> - a sequence of the relative dimensions.
607 std::vector<int> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
609 std::vector<std::string> fams(1,std::string(fam));
610 return getFamsNonEmptyLevelsExt(fams);
613 std::string MEDFileMesh::GetMagicFamilyStr()
615 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
619 * Changes a name of every family, included in one group only, to be same as the group name.
620 * \throw If there are families with equal names in \a this mesh.
622 void MEDFileMesh::assignFamilyNameWithGroupName()
624 std::map<std::string, std::vector<std::string> > groups(_groups);
625 std::map<std::string,int> newFams;
626 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
628 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
629 if(grps.size()==1 && groups[grps[0]].size()==1)
631 if(newFams.find(grps[0])!=newFams.end())
633 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
634 throw INTERP_KERNEL::Exception(oss.str().c_str());
636 newFams[grps[0]]=(*it).second;
637 std::vector<std::string>& grps2=groups[grps[0]];
638 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
643 if(newFams.find((*it).first)!=newFams.end())
645 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
646 throw INTERP_KERNEL::Exception(oss.str().c_str());
648 newFams[(*it).first]=(*it).second;
656 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
658 * \return the removed groups.
660 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
662 std::vector<std::string> ret;
663 std::map<std::string, std::vector<std::string> > newGrps;
664 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
666 if((*it).second.empty())
667 ret.push_back((*it).first);
669 newGrps[(*it).first]=(*it).second;
677 * Removes a group from \a this mesh.
678 * \param [in] name - the name of the group to remove.
679 * \throw If no group with such a \a name exists.
681 void MEDFileMesh::removeGroup(const std::string& name)
683 std::string oname(name);
684 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
685 std::vector<std::string> grps=getGroupsNames();
686 if(it==_groups.end())
688 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
689 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
690 throw INTERP_KERNEL::Exception(oss.str().c_str());
696 * Removes a family from \a this mesh.
697 * \param [in] name - the name of the family to remove.
698 * \throw If no family with such a \a name exists.
700 void MEDFileMesh::removeFamily(const std::string& name)
702 std::string oname(name);
703 std::map<std::string, int >::iterator it=_families.find(oname);
704 std::vector<std::string> fams=getFamiliesNames();
705 if(it==_families.end())
707 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
708 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
709 throw INTERP_KERNEL::Exception(oss.str().c_str());
712 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
714 std::vector<std::string>& v=(*it3).second;
715 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
722 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
723 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
724 * family field whatever its level. This method also suppresses the orphan families.
726 * \return - The list of removed groups names.
728 * \sa MEDFileMesh::removeOrphanFamilies.
730 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
732 removeOrphanFamilies();
733 return removeEmptyGroups();
737 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
738 * 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.
740 * \return - The list of removed families names.
741 * \sa MEDFileMesh::removeOrphanGroups.
743 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
745 MCAuto<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
746 std::vector<std::string> ret;
747 if(!((DataArrayInt*)allFamIdsInUse))
749 ret=getFamiliesNames();
750 _families.clear(); _groups.clear();
753 std::map<std::string,int> famMap;
754 std::map<std::string, std::vector<std::string> > grps(_groups);
755 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
757 if(allFamIdsInUse->presenceOfValue((*it).second))
758 famMap[(*it).first]=(*it).second;
761 ret.push_back((*it).first);
762 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
763 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
765 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
766 std::vector<std::string>& famv=(*it3).second;
767 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
773 { _families=famMap; _groups=grps; }
778 * 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
779 * this family is orphan or not.
781 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
783 void MEDFileMesh::removeFamiliesReferedByNoGroups()
785 std::map<std::string,int> fams;
786 std::set<std::string> sfams;
787 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
788 sfams.insert((*it).first);
789 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
790 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
792 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
793 if(*it!=DFT_FAM_NAME)
794 _families.erase(*it);
798 * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities
799 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
800 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
802 * \sa MEDFileMesh::removeOrphanFamilies
804 void MEDFileMesh::rearrangeFamilies()
806 checkOrphanFamilyZero();
807 removeFamiliesReferedByNoGroups();
809 std::vector<int> levels(getNonEmptyLevelsExt());
810 std::set<int> idsRefed;
811 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
812 idsRefed.insert((*it).second);
813 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
815 const DataArrayInt *fams(0);
818 fams=getFamilyFieldAtLevel(*it);
820 catch(INTERP_KERNEL::Exception& e) { }
823 std::vector<bool> v(fams->getNumberOfTuples(),false);
824 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
825 fams->switchOnTupleEqualTo(*pt,v);
826 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
827 if(!unfetchedIds->empty())
829 MCAuto<DataArrayInt> newFams(fams->deepCopy());
830 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
831 setFamilyFieldArr(*it,newFams);
834 removeOrphanFamilies();
838 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
840 void MEDFileMesh::checkOrphanFamilyZero() const
842 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
844 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
846 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
847 throw INTERP_KERNEL::Exception(oss.str().c_str());
853 * Renames a group in \a this mesh.
854 * \param [in] oldName - a current name of the group to rename.
855 * \param [in] newName - a new group name.
856 * \throw If no group named \a oldName exists in \a this mesh.
857 * \throw If a group named \a newName already exists.
859 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
861 std::string oname(oldName);
862 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
863 std::vector<std::string> grps=getGroupsNames();
864 if(it==_groups.end())
866 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
867 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
868 throw INTERP_KERNEL::Exception(oss.str().c_str());
870 std::string nname(newName);
871 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
872 if(it2!=_groups.end())
874 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
875 throw INTERP_KERNEL::Exception(oss.str().c_str());
877 std::vector<std::string> cpy=(*it).second;
879 _groups[newName]=cpy;
883 * Changes an id of a family in \a this mesh.
884 * This method calls changeFamilyIdArr().
885 * \param [in] oldId - a current id of the family.
886 * \param [in] newId - a new family id.
888 void MEDFileMesh::changeFamilyId(int oldId, int newId)
890 changeFamilyIdArr(oldId,newId);
891 std::map<std::string,int> fam2;
892 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
894 if((*it).second==oldId)
895 fam2[(*it).first]=newId;
897 fam2[(*it).first]=(*it).second;
903 * Renames a family in \a this mesh.
904 * \param [in] oldName - a current name of the family to rename.
905 * \param [in] newName - a new family name.
906 * \throw If no family named \a oldName exists in \a this mesh.
907 * \throw If a family named \a newName already exists.
909 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
911 std::string oname(oldName);
912 std::map<std::string, int >::iterator it=_families.find(oname);
913 std::vector<std::string> fams=getFamiliesNames();
914 if(it==_families.end())
916 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
917 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
918 throw INTERP_KERNEL::Exception(oss.str().c_str());
920 std::string nname(newName);
921 std::map<std::string, int >::iterator it2=_families.find(nname);
922 if(it2!=_families.end())
924 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
925 throw INTERP_KERNEL::Exception(oss.str().c_str());
927 int cpy=(*it).second;
929 _families[newName]=cpy;
930 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
932 std::vector<std::string>& v=(*it3).second;
933 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
940 * Checks if \a this and another mesh contains the same families.
941 * \param [in] other - the mesh to compare with \a this one.
942 * \param [in,out] what - an unused parameter.
943 * \return bool - \c true if number of families and their ids are the same in the two
944 * meshes. Families with the id == \c 0 are not considered.
946 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
948 if(_families==other->_families)
950 std::map<std::string,int> fam0;
951 std::map<std::string,int> fam1;
952 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
954 fam0[(*it).first]=(*it).second;
955 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
957 fam1[(*it).first]=(*it).second;
962 * Checks if \a this and another mesh contains the same groups.
963 * \param [in] other - the mesh to compare with \a this one.
964 * \param [in,out] what - a string describing a difference of groups of the two meshes
965 * in case if this method returns \c false.
966 * \return bool - \c true if number of groups and families constituting them are the
967 * same in the two meshes.
969 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
971 if(_groups==other->_groups)
974 std::size_t sz=_groups.size();
975 if(sz!=other->_groups.size())
977 what="Groups differ because not same number !\n";
982 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
983 for(std::size_t i=0;i<sz && ret;i++,it1++)
985 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
986 if(it2!=other->_groups.end())
988 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
989 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
995 what="A group in first mesh exists not in other !\n";
1001 std::ostringstream oss; oss << "Groups description differs :\n";
1002 oss << "First group description :\n";
1003 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1005 oss << " Group \"" << (*it).first << "\" on following families :\n";
1006 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1007 oss << " \"" << *it2 << "\n";
1009 oss << "Second group description :\n";
1010 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1012 oss << " Group \"" << (*it).first << "\" on following families :\n";
1013 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1014 oss << " \"" << *it2 << "\n";
1022 * Checks if a group with a given name exists in \a this mesh.
1023 * \param [in] groupName - the group name.
1024 * \return bool - \c true the group \a groupName exists in \a this mesh.
1026 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1028 std::string grpName(groupName);
1029 return _groups.find(grpName)!=_groups.end();
1033 * Checks if a family with a given id exists in \a this mesh.
1034 * \param [in] famId - the family id.
1035 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1037 bool MEDFileMesh::existsFamily(int famId) const
1039 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1040 if((*it2).second==famId)
1046 * Checks if a family with a given name exists in \a this mesh.
1047 * \param [in] familyName - the family name.
1048 * \return bool - \c true the family \a familyName exists in \a this mesh.
1050 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1052 std::string fname(familyName);
1053 return _families.find(fname)!=_families.end();
1057 * Sets an id of a family.
1058 * \param [in] familyName - the family name.
1059 * \param [in] id - a new id of the family.
1061 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1063 std::string fname(familyName);
1064 _families[fname]=id;
1067 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1069 std::string fname(familyName);
1070 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1071 if((*it).second==id)
1073 if((*it).first!=familyName)
1075 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1076 throw INTERP_KERNEL::Exception(oss.str().c_str());
1079 _families[fname]=id;
1083 * Adds a family to \a this mesh.
1084 * \param [in] familyName - a name of the family.
1085 * \param [in] famId - an id of the family.
1086 * \throw If a family with the same name or id already exists in \a this mesh.
1088 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1090 std::string fname(familyName);
1091 std::map<std::string,int>::const_iterator it=_families.find(fname);
1092 if(it==_families.end())
1094 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1095 if((*it2).second==famId)
1097 std::ostringstream oss;
1098 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1099 throw INTERP_KERNEL::Exception(oss.str().c_str());
1101 _families[fname]=famId;
1105 if((*it).second!=famId)
1107 std::ostringstream oss;
1108 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1109 throw INTERP_KERNEL::Exception(oss.str().c_str());
1115 * Creates a group including all mesh entities of given dimension.
1116 * \warning This method does \b not guarantee that the created group includes mesh
1117 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1118 * present in family fields of different dimensions. To assure this, call
1119 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1120 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1122 * \param [in] groupName - a name of the new group.
1123 * \throw If a group named \a groupName already exists.
1124 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1125 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1127 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1129 std::string grpName(groupName);
1130 std::vector<int> levs=getNonEmptyLevelsExt();
1131 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1133 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1134 oss << "Available relative ext levels are : ";
1135 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1136 throw INTERP_KERNEL::Exception(oss.str().c_str());
1138 if(existsGroup(groupName))
1140 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1141 oss << "Already existing groups are : ";
1142 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1143 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1144 throw INTERP_KERNEL::Exception(oss.str().c_str());
1146 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1148 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1149 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1150 std::vector<std::string> familiesOnWholeGroup;
1151 for(const int *it=famIds->begin();it!=famIds->end();it++)
1154 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1156 _groups[grpName]=familiesOnWholeGroup;
1160 * Ensures that given family ids do not present in family fields of dimensions different
1161 * than given ones. If a family id is present in the family fields of dimensions different
1162 * than the given ones, a new family is created and the whole data is updated accordingly.
1163 * \param [in] famIds - a sequence of family ids to check.
1164 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1165 * famIds should exclusively belong.
1166 * \return bool - \c true if no modification is done in \a this mesh by this method.
1168 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1170 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1171 std::vector<int> levs=getNonEmptyLevelsExt();
1172 std::set<int> levs2(levs.begin(),levs.end());
1173 std::vector<int> levsToTest;
1174 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1175 std::set<int> famIds2(famIds.begin(),famIds.end());
1178 if(!_families.empty())
1179 maxFamId=getMaxFamilyId()+1;
1180 std::vector<std::string> allFams=getFamiliesNames();
1181 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1183 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1186 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1187 std::vector<int> tmp;
1188 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1189 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1192 std::string famName=getFamilyNameGivenId(*it2);
1193 std::ostringstream oss; oss << "Family_" << maxFamId;
1194 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1195 addFamilyOnAllGroupsHaving(famName,zeName);
1196 _families[zeName]=maxFamId;
1197 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1206 * Adds a family to a given group in \a this mesh. If the group with a given name does
1207 * not exist, it is created.
1208 * \param [in] grpName - the name of the group to add the family in.
1209 * \param [in] famName - the name of the family to add to the group named \a grpName.
1210 * \throw If \a grpName or \a famName is an empty string.
1211 * \throw If no family named \a famName is present in \a this mesh.
1213 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1215 std::string grpn(grpName);
1216 std::string famn(famName);
1217 if(grpn.empty() || famn.empty())
1218 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1219 std::vector<std::string> fams=getFamiliesNames();
1220 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1222 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1223 oss << "Create this family or choose an existing one ! Existing fams are : ";
1224 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1225 throw INTERP_KERNEL::Exception(oss.str().c_str());
1227 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1228 if(it==_groups.end())
1230 _groups[grpn].push_back(famn);
1234 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1235 if(it2==(*it).second.end())
1236 (*it).second.push_back(famn);
1241 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1242 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1243 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1245 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1247 std::string famNameCpp(famName);
1248 std::string otherCpp(otherFamName);
1249 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1251 std::vector<std::string>& v=(*it).second;
1252 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1254 v.push_back(otherCpp);
1260 * \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).
1261 * \parma [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)
1263 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1266 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1267 std::string grpName(ids->getName());
1269 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1270 ids->checkStrictlyMonotonic(true);
1271 famArr->incrRef(); MCAuto<DataArrayInt> famArrTmp(famArr);
1272 std::vector<std::string> grpsNames=getGroupsNames();
1273 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1275 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1276 throw INTERP_KERNEL::Exception(oss.str().c_str());
1278 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1279 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1280 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1281 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1282 std::vector<int> familyIds;
1283 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1284 int maxVal=getTheMaxAbsFamilyId()+1;
1285 std::map<std::string,int> families(_families);
1286 std::map<std::string, std::vector<std::string> > groups(_groups);
1287 std::vector<std::string> fams;
1288 bool created(false);
1289 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1291 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1292 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1293 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1294 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1297 bool isFamPresent=false;
1298 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1299 isFamPresent=(*itl)->presenceOfValue(*famId);
1301 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1304 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1305 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1306 fams.push_back(locFamName);
1307 if(existsFamily(*famId))
1309 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1310 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1313 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1317 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1318 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1319 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1320 if(existsFamily(*famId))
1322 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1323 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1328 for(std::size_t i=0;i<familyIds.size();i++)
1330 DataArrayInt *da=idsPerfamiliyIds[i];
1331 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1335 _groups[grpName]=fams;
1338 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1340 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1343 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1345 std::string fam(familyNameToChange);
1346 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1348 std::vector<std::string>& fams((*it).second);
1349 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1353 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1359 * Returns a name of the family having a given id or, if no such a family exists, creates
1360 * a new uniquely named family and returns its name.
1361 * \param [in] id - the id of the family whose name is required.
1362 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1363 * \return std::string - the name of the existing or the created family.
1364 * \throw If it is not possible to create a unique family name.
1366 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1368 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1372 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1373 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1374 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1375 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1377 * This method will throws an exception if it is not possible to create a unique family name.
1379 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1381 std::vector<std::string> famAlreadyExisting(families.size());
1383 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1385 if((*it).second!=id)
1387 famAlreadyExisting[ii]=(*it).first;
1396 std::ostringstream oss; oss << "Family_" << id;
1397 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1403 * Sets names and ids of all families in \a this mesh.
1404 * \param [in] info - a map of a family name to a family id.
1406 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1412 * Sets names of all groups and families constituting them in \a this mesh.
1413 * \param [in] info - a map of a group name to a vector of names of families
1414 * constituting the group.
1416 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1422 * Returns an id of the family having a given name.
1423 * \param [in] name - the name of the family of interest.
1424 * \return int - the id of the family of interest.
1425 * \throw If no family with such a \a name exists.
1427 int MEDFileMesh::getFamilyId(const std::string& name) const
1429 std::map<std::string, int>::const_iterator it=_families.find(name);
1430 if(it==_families.end())
1432 std::vector<std::string> fams(getFamiliesNames());
1433 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1434 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1435 throw INTERP_KERNEL::Exception(oss.str().c_str());
1437 return (*it).second;
1441 * Returns ids of the families having given names.
1442 * \param [in] fams - a sequence of the names of families of interest.
1443 * \return std::vector<int> - a sequence of the ids of families of interest.
1444 * \throw If \a fams contains a name of an inexistent family.
1446 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1448 std::vector<int> ret(fams.size());
1450 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1452 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1453 if(it2==_families.end())
1455 std::vector<std::string> fams2=getFamiliesNames();
1456 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1457 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1458 throw INTERP_KERNEL::Exception(oss.str().c_str());
1460 ret[i]=(*it2).second;
1466 * Returns a maximal abs(id) of families in \a this mesh.
1467 * \return int - the maximal norm of family id.
1468 * \throw If there are no families in \a this mesh.
1470 int MEDFileMesh::getMaxAbsFamilyId() const
1472 if(_families.empty())
1473 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1474 int ret=-std::numeric_limits<int>::max();
1475 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1477 ret=std::max(std::abs((*it).second),ret);
1483 * Returns a maximal id of families in \a this mesh.
1484 * \return int - the maximal family id.
1485 * \throw If there are no families in \a this mesh.
1487 int MEDFileMesh::getMaxFamilyId() const
1489 if(_families.empty())
1490 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1491 int ret=-std::numeric_limits<int>::max();
1492 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1494 ret=std::max((*it).second,ret);
1500 * Returns a minimal id of families in \a this mesh.
1501 * \return int - the minimal family id.
1502 * \throw If there are no families in \a this mesh.
1504 int MEDFileMesh::getMinFamilyId() const
1506 if(_families.empty())
1507 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1508 int ret=std::numeric_limits<int>::max();
1509 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1511 ret=std::min((*it).second,ret);
1517 * Returns a maximal id of families in \a this mesh. Not only named families are
1518 * considered but all family fields as well.
1519 * \return int - the maximal family id.
1521 int MEDFileMesh::getTheMaxAbsFamilyId() const
1523 int m1=-std::numeric_limits<int>::max();
1524 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1525 m1=std::max(std::abs((*it).second),m1);
1526 int m2=getMaxAbsFamilyIdInArrays();
1527 return std::max(m1,m2);
1531 * Returns a maximal id of families in \a this mesh. Not only named families are
1532 * considered but all family fields as well.
1533 * \return int - the maximal family id.
1535 int MEDFileMesh::getTheMaxFamilyId() const
1537 int m1=-std::numeric_limits<int>::max();
1538 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1539 m1=std::max((*it).second,m1);
1540 int m2=getMaxFamilyIdInArrays();
1541 return std::max(m1,m2);
1545 * Returns a minimal id of families in \a this mesh. Not only named families are
1546 * considered but all family fields as well.
1547 * \return int - the minimal family id.
1549 int MEDFileMesh::getTheMinFamilyId() const
1551 int m1=std::numeric_limits<int>::max();
1552 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1553 m1=std::min((*it).second,m1);
1554 int m2=getMinFamilyIdInArrays();
1555 return std::min(m1,m2);
1559 * This method only considers the maps. The contain of family array is ignored here.
1561 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1563 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1565 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1567 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1568 v.insert((*it).second);
1569 ret->alloc((int)v.size(),1);
1570 std::copy(v.begin(),v.end(),ret->getPointer());
1575 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1577 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1579 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1581 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1582 MCAuto<DataArrayInt> ret;
1583 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1585 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1586 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1587 if((DataArrayInt *) ret)
1588 ret=dv->buildUnion(ret);
1596 * true is returned if no modification has been needed. false if family
1597 * renumbering has been needed.
1599 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1601 std::vector<int> levs=getNonEmptyLevelsExt();
1602 std::set<int> allFamIds;
1603 int maxId=getMaxFamilyId()+1;
1604 std::map<int,std::vector<int> > famIdsToRenum;
1605 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1607 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1610 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1612 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1614 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1616 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1619 if(famIdsToRenum.empty())
1621 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1622 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1624 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1625 int *famIdsToChange=fam->getPointer();
1626 std::map<int,int> ren;
1627 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1629 if(allIds->presenceOfValue(*it3))
1631 std::string famName=getFamilyNameGivenId(*it3);
1632 std::vector<std::string> grps=getGroupsOnFamily(famName);
1635 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1636 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1637 addFamilyOnGrp((*it4),newFam);
1640 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1641 for(const int *id=ids->begin();id!=ids->end();id++)
1642 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1648 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1649 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1650 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1651 * This method will throw an exception if a same family id is detected in different level.
1652 * \warning This policy is the opposite of those in MED file documentation ...
1654 void MEDFileMesh::normalizeFamIdsTrio()
1656 ensureDifferentFamIdsPerLevel();
1657 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1658 std::vector<int> levs=getNonEmptyLevelsExt();
1659 std::set<int> levsS(levs.begin(),levs.end());
1660 std::set<std::string> famsFetched;
1661 std::map<std::string,int> families;
1662 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1665 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1669 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1670 std::map<int,int> ren;
1671 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1673 int nbOfTuples=fam->getNumberOfTuples();
1674 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1675 for(int *w=start;w!=start+nbOfTuples;w++)
1677 for(const int *it=tmp->begin();it!=tmp->end();it++)
1679 if(allIds->presenceOfValue(*it))
1681 std::string famName=getFamilyNameGivenId(*it);
1682 families[famName]=ren[*it];
1683 famsFetched.insert(famName);
1688 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1691 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1695 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1696 std::map<int,int> ren;
1697 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1699 int nbOfTuples=fam->getNumberOfTuples();
1700 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1701 for(int *w=start;w!=start+nbOfTuples;w++)
1703 for(const int *it=tmp->begin();it!=tmp->end();it++)
1705 if(allIds->presenceOfValue(*it))
1707 std::string famName=getFamilyNameGivenId(*it);
1708 families[famName]=ren[*it];
1709 famsFetched.insert(famName);
1714 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1716 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1719 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1720 fam->fillWithZero();
1721 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1722 if(allIds->presenceOfValue(*it3))
1724 std::string famName=getFamilyNameGivenId(*it3);
1725 families[famName]=0;
1726 famsFetched.insert(famName);
1731 std::vector<std::string> allFams=getFamiliesNames();
1732 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1733 std::set<std::string> unFetchedIds;
1734 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1735 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1736 families[*it4]=_families[*it4];
1741 * This method normalizes fam id with the following policy.
1742 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1743 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1744 * This method will throw an exception if a same family id is detected in different level.
1746 void MEDFileMesh::normalizeFamIdsMEDFile()
1748 ensureDifferentFamIdsPerLevel();
1749 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1750 std::vector<int> levs=getNonEmptyLevelsExt();
1751 std::set<int> levsS(levs.begin(),levs.end());
1752 std::set<std::string> famsFetched;
1753 std::map<std::string,int> families;
1755 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1758 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1761 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1762 std::map<int,int> ren;
1763 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1765 int nbOfTuples=fam->getNumberOfTuples();
1766 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1767 for(int *w=start;w!=start+nbOfTuples;w++)
1769 for(const int *it=tmp->begin();it!=tmp->end();it++)
1771 if(allIds->presenceOfValue(*it))
1773 std::string famName=getFamilyNameGivenId(*it);
1774 families[famName]=ren[*it];
1775 famsFetched.insert(famName);
1781 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1783 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1786 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1787 std::map<int,int> ren;
1788 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1790 int nbOfTuples=fam->getNumberOfTuples();
1791 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1792 for(int *w=start;w!=start+nbOfTuples;w++)
1794 for(const int *it=tmp->begin();it!=tmp->end();it++)
1796 if(allIds->presenceOfValue(*it))
1798 std::string famName=getFamilyNameGivenId(*it);
1799 families[famName]=ren[*it];
1800 famsFetched.insert(famName);
1806 std::vector<std::string> allFams=getFamiliesNames();
1807 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1808 std::set<std::string> unFetchedIds;
1809 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1810 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1811 families[*it4]=_families[*it4];
1816 * Returns a name of the family by its id. If there are several families having the given
1817 * id, the name first in lexical order is returned.
1818 * \param [in] id - the id of the family whose name is required.
1819 * \return std::string - the name of the found family.
1820 * \throw If no family with the given \a id exists.
1822 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1824 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1825 if((*it).second==id)
1827 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1828 throw INTERP_KERNEL::Exception(oss.str().c_str());
1832 * Returns a string describing \a this mesh. This description includes the mesh name and
1833 * the mesh description string.
1834 * \return std::string - the mesh information string.
1836 std::string MEDFileMesh::simpleRepr() const
1838 std::ostringstream oss;
1839 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1840 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1841 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1846 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1847 * an empty one is created.
1849 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1851 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1854 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1855 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1856 arr->fillWithZero();
1857 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1858 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1862 * Returns ids of mesh entities contained in a given group of a given dimension.
1863 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1865 * \param [in] grp - the name of the group of interest.
1866 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1867 * returned instead of ids.
1868 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1869 * numbers, if available and required, of mesh entities of the group. The caller
1870 * is to delete this array using decrRef() as it is no more needed.
1871 * \throw If the name of a nonexistent group is specified.
1872 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1874 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1876 std::vector<std::string> tmp(1);
1878 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1884 * Returns ids of mesh entities contained in given groups of a given dimension.
1885 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1887 * \param [in] grps - the names of the groups of interest.
1888 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1889 * returned instead of ids.
1890 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1891 * numbers, if available and required, of mesh entities of the groups. The caller
1892 * is to delete this array using decrRef() as it is no more needed.
1893 * \throw If the name of a nonexistent group is present in \a grps.
1894 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1896 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1898 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1899 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1903 * Returns ids of mesh entities contained in a given family of a given dimension.
1904 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1906 * \param [in] fam - the name of the family of interest.
1907 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1908 * returned instead of ids.
1909 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1910 * numbers, if available and required, of mesh entities of the family. The caller
1911 * is to delete this array using decrRef() as it is no more needed.
1912 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1914 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1916 std::vector<std::string> tmp(1);
1918 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1924 * Returns ids of nodes contained in a given group.
1925 * \param [in] grp - the name of the group of interest.
1926 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1927 * returned instead of ids.
1928 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1929 * numbers, if available and required, of nodes of the group. The caller
1930 * is to delete this array using decrRef() as it is no more needed.
1931 * \throw If the name of a nonexistent group is specified.
1932 * \throw If the family field is missing for nodes.
1934 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1936 std::vector<std::string> tmp(1);
1938 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1944 * Returns ids of nodes contained in given groups.
1945 * \param [in] grps - the names of the groups of interest.
1946 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1947 * returned instead of ids.
1948 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1949 * numbers, if available and required, of nodes of the groups. The caller
1950 * is to delete this array using decrRef() as it is no more needed.
1951 * \throw If the name of a nonexistent group is present in \a grps.
1952 * \throw If the family field is missing for nodes.
1954 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1956 return getGroupsArr(1,grps,renum);
1960 * Returns ids of nodes contained in a given group.
1961 * \param [in] grp - the name of the group of interest.
1962 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1963 * returned instead of ids.
1964 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1965 * numbers, if available and required, of nodes of the group. The caller
1966 * is to delete this array using decrRef() as it is no more needed.
1967 * \throw If the name of a nonexistent group is specified.
1968 * \throw If the family field is missing for nodes.
1970 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1972 std::vector<std::string> tmp(1);
1974 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1980 * Returns ids of nodes contained in given families.
1981 * \param [in] fams - the names of the families of interest.
1982 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1983 * returned instead of ids.
1984 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1985 * numbers, if available and required, of nodes of the families. The caller
1986 * is to delete this array using decrRef() as it is no more needed.
1987 * \throw If the family field is missing for nodes.
1989 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1991 return getFamiliesArr(1,fams,renum);
1995 * Adds groups of given dimension and creates corresponding families and family fields
1996 * given ids of mesh entities of each group.
1997 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1998 * \param [in] grps - a sequence of arrays of ids each describing a group.
1999 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2001 * \throw If names of some groups in \a grps are equal.
2002 * \throw If \a grps includes a group with an empty name.
2003 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2004 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2006 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2010 std::set<std::string> grpsName;
2011 std::vector<std::string> grpsName2(grps.size());
2014 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2016 grpsName.insert((*it)->getName());
2017 grpsName2[i]=(*it)->getName();
2019 if(grpsName.size()!=grps.size())
2020 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2021 if(grpsName.find(std::string(""))!=grpsName.end())
2022 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2023 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2024 MCAuto<DataArrayInt> fam;
2025 std::vector< std::vector<int> > fidsOfGroups;
2028 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2032 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2033 for(unsigned int ii=0;ii<grps.size();ii++)
2035 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2036 grps2[ii]->setName(grps[ii]->getName());
2038 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2039 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2042 if(!_families.empty())
2043 offset=getMaxAbsFamilyId()+1;
2044 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2045 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2046 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2047 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2051 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2052 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2053 * For the moment, the two last input parameters are not taken into account.
2055 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2057 std::map<int,std::string> famInv;
2058 for(const int *it=famIds->begin();it!=famIds->end();it++)
2060 std::ostringstream oss;
2061 oss << "Family_" << (*it);
2062 _families[oss.str()]=(*it);
2063 famInv[*it]=oss.str();
2066 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2068 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2070 _groups[grpNames[i]].push_back(famInv[*it2]);
2075 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2077 std::vector<int> levs(getNonEmptyLevels());
2078 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2079 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2081 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2082 ret.insert(ret.end(),elts.begin(),elts.end());
2088 * \sa getAllDistributionOfTypes
2090 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2092 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2093 return mLev->getDistributionOfTypes();
2096 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2098 loadLL(fid,mName,dt,it,mrs);
2099 loadJointsFromFile(fid);
2100 loadEquivalences(fid);
2103 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2105 famArr->applyLin(offset>0?1:-1,offset,0);
2106 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2109 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2110 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2115 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2116 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2117 * If this method fails to find such a name it will throw an exception.
2119 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2122 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2125 std::size_t len=nameTry.length();
2126 for(std::size_t ii=1;ii<len;ii++)
2128 std::string tmp=nameTry.substr(ii,len-ii);
2129 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2135 for(std::size_t i=1;i<30;i++)
2137 std::string tmp1(nameTry.at(0),i);
2139 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2145 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2147 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2149 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2152 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2154 std::size_t nbOfChunks=code.size()/3;
2155 if(code.size()%3!=0)
2156 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2158 for(std::size_t i=0;i<nbOfChunks;i++)
2167 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2168 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2169 * If _name is not empty and that 'm' has the same name nothing is done.
2170 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2172 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2175 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2180 std::string name(m->getName());
2185 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2186 oss << name << "' ! Names must match !";
2187 throw INTERP_KERNEL::Exception(oss.str().c_str());
2191 if(_desc_name.empty())
2192 _desc_name=m->getDescription();
2195 std::string name(m->getDescription());
2198 if(_desc_name!=name)
2200 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2201 oss << name << "' ! Names must match !";
2202 throw INTERP_KERNEL::Exception(oss.str().c_str());
2208 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2210 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2211 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2213 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2214 oss << " - Groups lying on this family : ";
2215 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2216 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2217 oss << std::endl << std::endl;
2222 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2223 * file. The mesh to load is specified by its name and numbers of a time step and an
2225 * \param [in] fileName - the name of MED file to read.
2226 * \param [in] mName - the name of the mesh to read.
2227 * \param [in] dt - the number of a time step.
2228 * \param [in] it - the number of an iteration.
2229 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2230 * mesh using decrRef() as it is no more needed.
2231 * \throw If the file is not readable.
2232 * \throw If there is no mesh with given attributes in the file.
2233 * \throw If the mesh in the file is not an unstructured one.
2235 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2237 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2238 return New(fid,mName,dt,it,mrs);
2241 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2243 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2247 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2248 * file. The first mesh in the file is loaded.
2249 * \param [in] fileName - the name of MED file to read.
2250 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2251 * mesh using decrRef() as it is no more needed.
2252 * \throw If the file is not readable.
2253 * \throw If there is no meshes in the file.
2254 * \throw If the mesh in the file is not an unstructured one.
2256 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2258 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2259 return New(fid,mrs);
2263 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2265 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2268 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2269 throw INTERP_KERNEL::Exception(oss.str().c_str());
2272 MEDCoupling::MEDCouplingMeshType meshType;
2274 MEDCoupling::MEDCouplingAxisType dummy3;
2275 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2276 return T::New(fid,ms.front(),dt,it,mrs);
2279 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2281 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2285 * \b WARNING this implementation is dependant from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2286 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2288 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2291 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2292 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2293 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2294 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2296 m2D->setCoords(m3D->getCoords());
2297 ret->setMeshAtLevel(0,m3D);
2298 ret->setMeshAtLevel(-1,m2D);
2299 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2304 * Returns an empty instance of MEDFileUMesh.
2305 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2306 * mesh using decrRef() as it is no more needed.
2308 MEDFileUMesh *MEDFileUMesh::New()
2310 return new MEDFileUMesh;
2314 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2315 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2316 * \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.
2317 * 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
2318 * at most the memory consumtion.
2320 * \param [in] fileName - the name of the file.
2321 * \param [in] mName - the name of the mesh to be read.
2322 * \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.
2323 * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
2324 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2325 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2326 * \param [in] mrs - the request for what to be loaded.
2327 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2329 MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2331 MEDFileUtilities::CheckFileForRead(fileName);
2332 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2333 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2337 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2338 * This method is \b NOT wrapped into python.
2340 MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2342 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2343 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2347 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2349 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2350 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
2354 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2356 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2357 ret.push_back((const DataArrayDouble*)_coords);
2358 ret.push_back((const DataArrayInt *)_fam_coords);
2359 ret.push_back((const DataArrayInt *)_num_coords);
2360 ret.push_back((const DataArrayInt *)_global_num_coords);
2361 ret.push_back((const DataArrayInt *)_rev_num_coords);
2362 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2363 ret.push_back((const PartDefinition *)_part_coords);
2364 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2365 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2366 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2367 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2371 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2373 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2377 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2379 return new MEDFileUMesh;
2382 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2384 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2385 ret->deepCpyEquivalences(*this);
2386 if(_coords.isNotNull())
2387 ret->_coords=_coords->deepCopy();
2388 if(_fam_coords.isNotNull())
2389 ret->_fam_coords=_fam_coords->deepCopy();
2390 if(_num_coords.isNotNull())
2391 ret->_num_coords=_num_coords->deepCopy();
2392 if(_global_num_coords.isNotNull())
2393 ret->_global_num_coords=_global_num_coords->deepCopy();
2394 if(_rev_num_coords.isNotNull())
2395 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2396 if(_name_coords.isNotNull())
2397 ret->_name_coords=_name_coords->deepCopy();
2399 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2401 if((const MEDFileUMeshSplitL1 *)(*it))
2402 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2404 if((const PartDefinition*)_part_coords)
2405 ret->_part_coords=_part_coords->deepCopy();
2410 * Checks if \a this and another mesh are equal.
2411 * \param [in] other - the mesh to compare with.
2412 * \param [in] eps - a precision used to compare real values.
2413 * \param [in,out] what - the string returning description of unequal data.
2414 * \return bool - \c true if the meshes are equal, \c false, else.
2416 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2418 if(!MEDFileMesh::isEqual(other,eps,what))
2420 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2423 what="Mesh types differ ! This is unstructured and other is NOT !";
2426 clearNonDiscrAttributes();
2427 otherC->clearNonDiscrAttributes();
2428 const DataArrayDouble *coo1=_coords;
2429 const DataArrayDouble *coo2=otherC->_coords;
2430 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2432 what="Mismatch of coordinates ! One is defined and not other !";
2437 bool ret=coo1->isEqual(*coo2,eps);
2440 what="Coords differ !";
2445 const DataArrayInt *famc1(_fam_coords),*famc2(otherC->_fam_coords);
2446 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2448 what="Mismatch of families arr on nodes ! One is defined and not other !";
2453 bool ret=famc1->isEqual(*famc2);
2456 what="Families arr on node differ !";
2462 const DataArrayInt *numc1(_num_coords),*numc2(otherC->_num_coords);
2463 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2465 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2470 bool ret=numc1->isEqual(*numc2);
2473 what="Numbering arr on node differ !";
2479 const DataArrayInt *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
2480 if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
2482 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2487 bool ret=gnumc1->isEqual(*gnumc2);
2490 what="Global numbering arr on node differ !";
2496 const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
2497 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2499 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2504 bool ret=namec1->isEqual(*namec2);
2507 what="Names arr on node differ !";
2512 if(_ms.size()!=otherC->_ms.size())
2514 what="Number of levels differs !";
2517 std::size_t sz=_ms.size();
2518 for(std::size_t i=0;i<sz;i++)
2520 const MEDFileUMeshSplitL1 *s1=_ms[i];
2521 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2522 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2524 what="Mismatch of presence of sub levels !";
2529 bool ret=s1->isEqual(s2,eps,what);
2534 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2537 if((!pd0 && pd1) || (pd0 && !pd1))
2539 what=std::string("node part def is defined only for one among this or other !");
2542 return pd0->isEqual(pd1,what);
2546 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2547 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2548 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2549 * \throw if internal family array is inconsistent
2550 * \sa checkSMESHConsistency()
2552 void MEDFileUMesh::checkConsistency() const
2554 if(!_coords || !_coords->isAllocated())
2557 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2559 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2560 if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
2561 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2565 int nbCoo = _coords->getNumberOfTuples();
2566 if (_fam_coords.isNotNull())
2567 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2568 if (_num_coords.isNotNull())
2570 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2572 int maxValue=_num_coords->getMaxValue(pos);
2573 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2574 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2576 if (_global_num_coords.isNotNull())
2578 _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
2580 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2581 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2582 if (_num_coords && !_num_coords->hasUniqueValues())
2583 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2585 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2586 // Now sub part check:
2587 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2588 it != _ms.end(); it++)
2589 (*it)->checkConsistency();
2594 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2595 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2596 * entities as it likes), or non overlapping between all sub-levels.
2597 * \throw if the condition above is not respected
2599 void MEDFileUMesh::checkSMESHConsistency() const
2602 // For all sub-levels, numbering is either always null or with void intersection:
2605 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2606 std::vector< const DataArrayInt * > v;
2607 bool voidOrNot = ((*it)->_num == 0);
2608 for (it++; it != _ms.end(); it++)
2609 if( ((*it)->_num == 0) != voidOrNot )
2610 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2611 else if (!voidOrNot)
2612 v.push_back((*it)->_num);
2615 // don't forget the 1st one:
2616 v.push_back(_ms[0]->_num);
2617 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2618 if (inter->getNumberOfTuples())
2619 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2625 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2626 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2628 void MEDFileUMesh::clearNodeAndCellNumbers()
2630 _num_coords.nullify();
2631 _rev_num_coords.nullify();
2632 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
2634 (*it)->_num.nullify();
2635 (*it)->_rev_num.nullify();
2636 (*it)->_global_num_coords.nullify();
2641 * Clears redundant attributes of incorporated data arrays.
2643 void MEDFileUMesh::clearNonDiscrAttributes() const
2645 MEDFileMesh::clearNonDiscrAttributes();
2646 if(_coords.isNotNull())
2647 _coords->setName("");//This parameter is not discriminant for comparison
2648 if(_fam_coords.isNotNull())
2649 _fam_coords->setName("");//This parameter is not discriminant for comparison
2650 if(_num_coords.isNotNull())
2651 _num_coords->setName("");//This parameter is not discriminant for comparison
2652 if(_name_coords.isNotNull())
2653 _name_coords->setName("");//This parameter is not discriminant for comparison
2654 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2656 if((*it).isNotNull())
2657 (*it)->clearNonDiscrAttributes();
2661 void MEDFileUMesh::setName(const std::string& name)
2663 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2664 if((*it).isNotNull())
2665 (*it)->setName(name);
2666 MEDFileMesh::setName(name);
2669 MEDFileUMesh::MEDFileUMesh()
2673 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2676 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2678 catch(INTERP_KERNEL::Exception& e)
2684 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2685 * See MEDFileUMesh::LoadPartOf for detailed description.
2689 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2691 MEDFileUMeshL2 loaderl2;
2692 MEDCoupling::MEDCouplingMeshType meshType;
2695 MEDCoupling::MEDCouplingAxisType dummy3;
2696 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2697 if(meshType!=UNSTRUCTURED)
2699 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2700 throw INTERP_KERNEL::Exception(oss.str().c_str());
2702 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2703 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2707 * \brief Write joints in a file
2709 void MEDFileMesh::writeJoints(med_idt fid) const
2711 if ( _joints.isNotNull() )
2712 _joints->writeLL(fid);
2716 * \brief Load joints in a file or use provided ones
2718 //================================================================================
2720 * \brief Load joints in a file or use provided ones
2721 * \param [in] fid - MED file descriptor
2722 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2723 * Usually this joints are those just read by another iteration
2724 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2726 //================================================================================
2728 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2730 if ( toUseInstedOfReading )
2731 setJoints( toUseInstedOfReading );
2733 _joints = MEDFileJoints::New( fid, _name );
2736 void MEDFileMesh::loadEquivalences(med_idt fid)
2738 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2740 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2743 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2745 const MEDFileEquivalences *equiv(other._equiv);
2747 _equiv=equiv->deepCopy(this);
2750 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2752 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2753 if(!thisEq && !otherEq)
2755 if(thisEq && otherEq)
2756 return thisEq->isEqual(otherEq,what);
2759 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2764 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2766 const MEDFileEquivalences *equiv(_equiv);
2769 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2770 _equiv->getRepr(oss);
2773 void MEDFileMesh::checkCartesian() const
2775 if(getAxisType()!=AX_CART)
2777 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()) << ").";
2778 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2779 oss << " - call setAxisType(AX_CART)" << std::endl;
2780 oss << " - call cartesianize()";
2781 throw INTERP_KERNEL::Exception(oss.str().c_str());
2786 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2788 int MEDFileMesh::getNumberOfJoints() const
2790 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2794 * \brief Return joints with all adjacent mesh domains
2796 MEDFileJoints * MEDFileMesh::getJoints() const
2798 return const_cast<MEDFileJoints*>(& (*_joints));
2801 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2803 if ( joints != _joints )
2812 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2814 * \sa loadPartUMeshFromFile
2816 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2818 MEDFileUMeshL2 loaderl2;
2819 MEDCoupling::MEDCouplingMeshType meshType;
2822 MEDCoupling::MEDCouplingAxisType axType;
2823 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2824 setAxisType(axType);
2825 if(meshType!=UNSTRUCTURED)
2827 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2828 throw INTERP_KERNEL::Exception(oss.str().c_str());
2830 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2831 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2832 // Structure element part...
2835 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2836 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2840 _elt_str.resize(nModels);
2841 for(int i=0;i<nModels;i++)
2842 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2845 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2847 int lev=loaderl2.getNumberOfLevels();
2849 for(int i=0;i<lev;i++)
2851 if(!loaderl2.emptyLev(i))
2852 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2856 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2858 setName(loaderl2.getName());
2859 setDescription(loaderl2.getDescription());
2860 setUnivName(loaderl2.getUnivName());
2861 setIteration(loaderl2.getIteration());
2862 setOrder(loaderl2.getOrder());
2863 setTimeValue(loaderl2.getTime());
2864 setTimeUnit(loaderl2.getTimeUnit());
2865 _coords=loaderl2.getCoords();
2866 if(!mrs || mrs->isNodeFamilyFieldReading())
2867 _fam_coords=loaderl2.getCoordsFamily();
2868 if(!mrs || mrs->isNodeNumFieldReading())
2869 _num_coords=loaderl2.getCoordsNum();
2870 if(!mrs || mrs->isNodeNameFieldReading())
2871 _name_coords=loaderl2.getCoordsName();
2872 if(!mrs || mrs->isGlobalNodeNumFieldReading())
2873 _global_num_coords=loaderl2.getGlobalCoordsNum();
2874 _part_coords=loaderl2.getPartDefOfCoo();
2878 MEDFileUMesh::~MEDFileUMesh()
2882 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2884 const DataArrayDouble *coo=_coords;
2885 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2886 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2887 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2888 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2889 int spaceDim=coo?coo->getNumberOfComponents():0;
2892 mdim=getMeshDimension();
2893 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2894 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2895 for(int i=0;i<spaceDim;i++)
2897 std::string info=coo->getInfoOnComponent(i);
2899 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2900 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
2901 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
2903 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2905 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2906 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2907 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2908 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2909 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2910 (*it)->write(fid,meshName,mdim);
2911 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2915 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2916 * \return std::vector<int> - a sequence of the relative dimensions.
2918 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2920 std::vector<int> ret;
2922 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2923 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2930 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2931 * \return std::vector<int> - a sequence of the relative dimensions.
2933 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2935 std::vector<int> ret0=getNonEmptyLevels();
2936 if((const DataArrayDouble *) _coords)
2938 std::vector<int> ret(ret0.size()+1);
2940 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2946 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2948 std::vector<int> ret;
2949 const DataArrayInt *famCoo(_fam_coords);
2953 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2955 const MEDFileUMeshSplitL1 *cur(*it);
2957 if(cur->getFamilyField())
2963 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2965 std::vector<int> ret;
2966 if(_num_coords.isNotNull())
2969 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2971 const MEDFileUMeshSplitL1 *cur(*it);
2973 if(cur->getNumberField())
2979 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2981 std::vector<int> ret;
2982 const DataArrayAsciiChar *nameCoo(_name_coords);
2986 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2988 const MEDFileUMeshSplitL1 *cur(*it);
2990 if(cur->getNameField())
2997 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2998 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2999 * \param [in] fams - the name of the family of interest.
3000 * \return std::vector<int> - a sequence of the relative dimensions.
3002 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
3004 std::vector<int> ret;
3005 std::vector<int> levs(getNonEmptyLevels());
3006 std::vector<int> famIds(getFamiliesIds(fams));
3007 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3008 if(_ms[-(*it)]->presenceOfOneFams(famIds))
3014 * Returns all relative mesh levels (including nodes) where given families are defined.
3015 * \param [in] fams - the names of the families of interest.
3016 * \return std::vector<int> - a sequence of the relative dimensions.
3018 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
3020 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
3021 const DataArrayInt *famCoords(_fam_coords);
3024 std::vector<int> famIds(getFamiliesIds(fams));
3025 if(famCoords->presenceOfValue(famIds))
3027 std::vector<int> ret(ret0.size()+1);
3029 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3036 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3038 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3039 if((const DataArrayInt *)_fam_coords)
3041 int val=_fam_coords->getMaxValue(tmp);
3042 ret=std::max(ret,std::abs(val));
3044 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3046 if((const MEDFileUMeshSplitL1 *)(*it))
3048 const DataArrayInt *da=(*it)->getFamilyField();
3051 int val=da->getMaxValue(tmp);
3052 ret=std::max(ret,std::abs(val));
3059 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3061 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3062 if((const DataArrayInt *)_fam_coords)
3064 int val=_fam_coords->getMaxValue(tmp);
3065 ret=std::max(ret,val);
3067 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3069 if((const MEDFileUMeshSplitL1 *)(*it))
3071 const DataArrayInt *da=(*it)->getFamilyField();
3074 int val=da->getMaxValue(tmp);
3075 ret=std::max(ret,val);
3082 int MEDFileUMesh::getMinFamilyIdInArrays() const
3084 int ret=std::numeric_limits<int>::max(),tmp=-1;
3085 if((const DataArrayInt *)_fam_coords)
3087 int val=_fam_coords->getMinValue(tmp);
3088 ret=std::min(ret,val);
3090 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3092 if((const MEDFileUMeshSplitL1 *)(*it))
3094 const DataArrayInt *da=(*it)->getFamilyField();
3097 int val=da->getMinValue(tmp);
3098 ret=std::min(ret,val);
3106 * Returns the dimension on cells in \a this mesh.
3107 * \return int - the mesh dimension.
3108 * \throw If there are no cells in this mesh.
3110 int MEDFileUMesh::getMeshDimension() const
3113 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3114 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3115 return (*it)->getMeshDimension()+lev;
3116 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3120 * Returns the space dimension of \a this mesh that is equal to number of components in
3121 * the node coordinates array.
3122 * \return int - the space dimension of \a this mesh.
3123 * \throw If the node coordinates array is not available.
3125 int MEDFileUMesh::getSpaceDimension() const
3127 const DataArrayDouble *coo=_coords;
3129 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3130 return coo->getNumberOfComponents();
3134 * Returns a string describing \a this mesh.
3135 * \return std::string - the mesh information string.
3137 std::string MEDFileUMesh::simpleRepr() const
3139 std::ostringstream oss;
3140 oss << MEDFileMesh::simpleRepr();
3141 const DataArrayDouble *coo=_coords;
3142 oss << "- The dimension of the space is ";
3143 static const char MSG1[]= "*** NO COORDS SET ***";
3144 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3146 oss << _coords->getNumberOfComponents() << std::endl;
3148 oss << MSG1 << std::endl;
3149 oss << "- Type of the mesh : UNSTRUCTURED\n";
3150 oss << "- Number of nodes : ";
3152 oss << _coords->getNumberOfTuples() << std::endl;
3154 oss << MSG1 << std::endl;
3155 std::size_t nbOfLev=_ms.size();
3156 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3157 for(std::size_t i=0;i<nbOfLev;i++)
3159 const MEDFileUMeshSplitL1 *lev=_ms[i];
3160 oss << " - Level #" << -((int) i) << " has dimension : ";
3163 oss << lev->getMeshDimension() << std::endl;
3164 lev->simpleRepr(oss);
3167 oss << MSG2 << std::endl;
3169 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3172 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3173 oss << "- Names of coordinates :" << std::endl;
3174 std::vector<std::string> vars=coo->getVarsOnComponent();
3175 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3176 oss << std::endl << "- Units of coordinates : " << std::endl;
3177 std::vector<std::string> units=coo->getUnitsOnComponent();
3178 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3180 oss << std::endl << std::endl;
3182 getEquivalencesRepr(oss);
3187 * Returns a full textual description of \a this mesh.
3188 * \return std::string - the string holding the mesh description.
3190 std::string MEDFileUMesh::advancedRepr() const
3192 return simpleRepr();
3196 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3197 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3198 * \return int - the number of entities.
3199 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3201 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3203 if(meshDimRelToMaxExt==1)
3205 if(!((const DataArrayDouble *)_coords))
3206 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3207 return _coords->getNumberOfTuples();
3209 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3213 * Returns the family field for mesh entities of a given dimension.
3214 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3215 * \return const DataArrayInt * - the family field. It is an array of ids of families
3216 * each mesh entity belongs to. It can be \c NULL.
3218 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3220 if(meshDimRelToMaxExt==1)
3222 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3223 return l1->getFamilyField();
3226 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3228 if(meshDimRelToMaxExt==1)
3230 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3231 return l1->getFamilyField();
3235 * Returns the optional numbers of mesh entities of a given dimension.
3236 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3237 * \return const DataArrayInt * - the array of the entity numbers.
3238 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3240 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3242 if(meshDimRelToMaxExt==1)
3244 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3245 return l1->getNumberField();
3248 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3250 if(meshDimRelToMaxExt==1)
3251 return _name_coords;
3252 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3253 return l1->getNameField();
3257 * 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).
3259 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3260 * \param [in] gt - The input geometric type for which the part definition is requested.
3261 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3263 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3265 if(meshDimRelToMaxExt==1)
3266 return _part_coords;
3267 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3268 return l1->getPartDef(gt);
3271 int MEDFileUMesh::getNumberOfNodes() const
3273 const DataArrayDouble *coo(_coords);
3275 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3276 return coo->getNumberOfTuples();
3279 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3281 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3282 return l1->getNumberOfCells();
3285 bool MEDFileUMesh::hasImplicitPart() const
3290 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3292 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3295 void MEDFileUMesh::releaseImplicitPartIfAny() const
3299 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3301 std::size_t sz(st.getNumberOfItems());
3302 for(std::size_t i=0;i<sz;i++)
3304 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3305 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3306 if(st[i].getPflName().empty())
3307 m->computeNodeIdsAlg(nodesFetched);
3310 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3311 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3312 m2->computeNodeIdsAlg(nodesFetched);
3317 MEDFileMesh *MEDFileUMesh::cartesianize() const
3319 if(getAxisType()==AX_CART)
3322 return const_cast<MEDFileUMesh *>(this);
3326 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3327 const DataArrayDouble *coords(_coords);
3329 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3330 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3331 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3332 if((const MEDFileUMeshSplitL1 *)(*it))
3333 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3334 ret->_coords=coordsCart;
3335 ret->setAxisType(AX_CART);
3340 bool MEDFileUMesh::presenceOfStructureElements() const
3342 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3343 if((*it).isNotNull())
3348 void MEDFileUMesh::killStructureElements()
3354 * Returns the optional numbers of mesh entities of a given dimension transformed using
3355 * DataArrayInt::invertArrayN2O2O2N().
3356 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3357 * \return const DataArrayInt * - the array of the entity numbers transformed using
3358 * DataArrayInt::invertArrayN2O2O2N().
3359 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3361 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3363 if(meshDimRelToMaxExt==1)
3365 if(_num_coords.isNotNull())
3366 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3367 return _rev_num_coords;
3369 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3370 return l1->getRevNumberField();
3374 * Returns a pointer to the node coordinates array of \a this mesh \b without
3375 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3377 DataArrayDouble *MEDFileUMesh::getCoords() const
3380 MCAuto<DataArrayDouble> tmp(_coords);
3381 if((DataArrayDouble *)tmp)
3389 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3390 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3392 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3393 * \param [in] grp - the name of the group whose mesh entities are included in the
3395 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3396 * according to the optional numbers of entities, if available.
3397 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3398 * delete this mesh using decrRef() as it is no more needed.
3399 * \throw If the name of a nonexistent group is specified.
3400 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3402 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3405 synchronizeTinyInfoOnLeaves();
3406 std::vector<std::string> tmp(1);
3408 return getGroups(meshDimRelToMaxExt,tmp,renum);
3412 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3413 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3415 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3416 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3418 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3419 * according to the optional numbers of entities, if available.
3420 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3421 * delete this mesh using decrRef() as it is no more needed.
3422 * \throw If a name of a nonexistent group is present in \a grps.
3423 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3425 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3428 synchronizeTinyInfoOnLeaves();
3429 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3430 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3431 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3432 zeRet->setName(grps[0]);
3433 return zeRet.retn();
3437 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3438 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3440 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3441 * \param [in] fam - the name of the family whose mesh entities are included in the
3443 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3444 * according to the optional numbers of entities, if available.
3445 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3446 * delete this mesh using decrRef() as it is no more needed.
3447 * \throw If a name of a nonexistent family is present in \a grps.
3448 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3450 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3453 synchronizeTinyInfoOnLeaves();
3454 std::vector<std::string> tmp(1);
3456 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3460 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3461 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3463 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3464 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3466 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3467 * according to the optional numbers of entities, if available.
3468 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3469 * delete this mesh using decrRef() as it is no more needed.
3470 * \throw If a name of a nonexistent family is present in \a fams.
3471 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3473 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3476 synchronizeTinyInfoOnLeaves();
3477 if(meshDimRelToMaxExt==1)
3479 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3480 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3481 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3485 std::vector<int> famIds=getFamiliesIds(fams);
3486 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3487 MCAuto<MEDCouplingUMesh> zeRet;
3489 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3491 zeRet=l1->getFamilyPart(0,0,renum);
3492 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3493 zeRet->setName(fams[0]);
3494 return zeRet.retn();
3498 * Returns ids of mesh entities contained in given families of a given dimension.
3499 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3501 * \param [in] fams - the names of the families of interest.
3502 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3503 * returned instead of ids.
3504 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3505 * numbers, if available and required, of mesh entities of the families. The caller
3506 * is to delete this array using decrRef() as it is no more needed.
3507 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3509 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3511 std::vector<int> famIds=getFamiliesIds(fams);
3512 if(meshDimRelToMaxExt==1)
3514 if((const DataArrayInt *)_fam_coords)
3516 MCAuto<DataArrayInt> da;
3518 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3520 da=_fam_coords->findIdsEqualList(0,0);
3522 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3527 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3529 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3531 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3533 return l1->getFamilyPartArr(0,0,renum);
3537 * Returns a MEDCouplingUMesh of a given relative dimension.
3538 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3539 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3540 * To build a valid MEDCouplingUMesh from the returned one in this case,
3541 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3542 * \param [in] meshDimRelToMax - the relative dimension of interest.
3543 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3544 * optional numbers of mesh entities.
3545 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3546 * delete using decrRef() as it is no more needed.
3547 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3549 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3552 synchronizeTinyInfoOnLeaves();
3553 if(meshDimRelToMaxExt==1)
3557 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3558 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3559 umesh->setCoords(cc);
3560 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3561 umesh->setName(getName());
3565 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3566 return l1->getWholeMesh(renum);
3569 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3571 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3572 return l1->getDistributionOfTypes();
3576 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3577 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3578 * optional numbers of mesh entities.
3579 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3580 * delete using decrRef() as it is no more needed.
3581 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3583 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3585 return getMeshAtLevel(0,renum);
3589 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3590 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3591 * optional numbers of mesh entities.
3592 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3593 * delete using decrRef() as it is no more needed.
3594 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3596 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3598 return getMeshAtLevel(-1,renum);
3602 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3603 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3604 * optional numbers of mesh entities.
3605 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3606 * delete using decrRef() as it is no more needed.
3607 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3609 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3611 return getMeshAtLevel(-2,renum);
3615 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3616 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3617 * optional numbers of mesh entities.
3618 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3619 * delete using decrRef() as it is no more needed.
3620 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3622 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3624 return getMeshAtLevel(-3,renum);
3628 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3629 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3630 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3631 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3633 void MEDFileUMesh::forceComputationOfParts() const
3635 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3637 const MEDFileUMeshSplitL1 *elt(*it);
3639 elt->forceComputationOfParts();
3644 * This method returns a vector of mesh parts containing each exactly one geometric type.
3645 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3646 * This method is only for memory aware users.
3647 * The returned pointers are **NOT** new object pointer. No need to mange them.
3649 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3652 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3653 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3657 * This method returns the part of \a this having the geometric type \a gt.
3658 * If such part is not existing an exception will be thrown.
3659 * The returned pointer is **NOT** new object pointer. No need to mange it.
3661 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3664 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3665 int lev=(int)cm.getDimension()-getMeshDimension();
3666 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3667 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3671 * This method returns for each geo types in \a this number of cells with this geo type.
3672 * 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.
3673 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3675 * \sa getDistributionOfTypes
3677 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3679 std::vector< std::pair<int,int> > ret;
3680 std::vector<int> nel(getNonEmptyLevels());
3681 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3683 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3684 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3686 int nbCells(getNumberOfCellsWithType(*it1));
3687 ret.push_back(std::pair<int,int>(*it1,nbCells));
3690 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3695 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3696 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3698 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3700 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3701 return sp->getGeoTypes();
3704 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3706 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3707 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3708 return sp->getNumberOfCellsWithType(ct);
3712 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3713 * \param [in] gt - the geometric type for which the family field is asked.
3714 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3715 * delete using decrRef() as it is no more needed.
3716 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3718 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3720 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3721 int lev=(int)cm.getDimension()-getMeshDimension();
3722 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3723 return sp->extractFamilyFieldOnGeoType(gt);
3727 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3728 * \param [in] gt - the geometric type for which the number field is asked.
3729 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3730 * delete using decrRef() as it is no more needed.
3731 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3733 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3735 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3736 int lev=(int)cm.getDimension()-getMeshDimension();
3737 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3738 return sp->extractNumberFieldOnGeoType(gt);
3742 * This method returns for specified geometric type \a gt the relative level to \a this.
3743 * If the relative level is empty an exception will be thrown.
3745 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3747 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3748 int ret((int)cm.getDimension()-getMeshDimension());
3749 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3753 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3755 if(meshDimRelToMaxExt==1)
3756 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3757 if(meshDimRelToMaxExt>1)
3758 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3759 int tracucedRk=-meshDimRelToMaxExt;
3760 if(tracucedRk>=(int)_ms.size())
3761 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3762 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3763 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3764 return _ms[tracucedRk];
3767 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3769 if(meshDimRelToMaxExt==1)
3770 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3771 if(meshDimRelToMaxExt>1)
3772 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3773 int tracucedRk=-meshDimRelToMaxExt;
3774 if(tracucedRk>=(int)_ms.size())
3775 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3776 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3777 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3778 return _ms[tracucedRk];
3781 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3783 if(-meshDimRelToMax>=(int)_ms.size())
3784 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3786 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3788 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3790 int ref=(*it)->getMeshDimension();
3791 if(ref+i!=meshDim-meshDimRelToMax)
3792 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3798 * Sets the node coordinates array of \a this mesh.
3799 * \param [in] coords - the new node coordinates array.
3800 * \throw If \a coords == \c NULL.
3802 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3805 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3806 if(coords==(DataArrayDouble *)_coords)
3808 coords->checkAllocated();
3809 int nbOfTuples(coords->getNumberOfTuples());
3810 _coords.takeRef(coords);
3811 _fam_coords=DataArrayInt::New();
3812 _fam_coords->alloc(nbOfTuples,1);
3813 _fam_coords->fillWithZero();
3814 _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
3815 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3816 if((MEDFileUMeshSplitL1 *)(*it))
3817 (*it)->setCoords(coords);
3821 * Change coords without changing anything concerning families and numbering on nodes.
3823 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3826 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3827 if(coords==(DataArrayDouble *)_coords)
3829 coords->checkAllocated();
3830 int nbOfTuples(coords->getNumberOfTuples());
3831 if(_coords.isNull())
3838 int oldNbTuples(_coords->getNumberOfTuples());
3839 if(oldNbTuples!=nbOfTuples)
3840 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3844 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3845 if((MEDFileUMeshSplitL1 *)(*it))
3846 (*it)->setCoords(coords);
3850 * Removes all groups of a given dimension in \a this mesh.
3851 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3852 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3854 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3856 if(meshDimRelToMaxExt==1)
3858 if((DataArrayInt *)_fam_coords)
3859 _fam_coords->fillWithZero();
3862 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3863 l1->eraseFamilyField();
3868 * Removes all families with ids not present in the family fields of \a this mesh.
3870 void MEDFileUMesh::optimizeFamilies()
3872 std::vector<int> levs=getNonEmptyLevelsExt();
3873 std::set<int> allFamsIds;
3874 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3876 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3877 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3879 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3882 std::set<std::string> famNamesToKill;
3883 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3885 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3886 famNamesToKill.insert((*it).first);
3888 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3889 _families.erase(*it);
3890 std::vector<std::string> grpNamesToKill;
3891 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3893 std::vector<std::string> tmp;
3894 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3896 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3897 tmp.push_back(*it2);
3902 tmp.push_back((*it).first);
3904 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3909 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3910 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3911 * The boundary is built according to the following method:
3912 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3913 * coordinates array is extended).
3914 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3915 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3916 * might not be duplicated at all.
3917 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3918 * other side of the group is no more a neighbor)
3919 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3920 * bordering the newly created boundary use the newly computed nodes.
3921 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3922 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3924 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3925 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3927 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3928 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3929 * \sa clearNodeAndCellNumbers()
3931 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3932 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3934 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3935 typedef MCAuto<DataArrayInt> DAInt;
3937 std::vector<int> levs=getNonEmptyLevels();
3938 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3939 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3940 MUMesh m0=getMeshAtLevel(0);
3941 MUMesh m1=getMeshAtLevel(-1);
3942 int nbNodes=m0->getNumberOfNodes();
3943 MUMesh m11=getGroup(-1,grpNameM1);
3944 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3945 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3946 DAInt nodeIdsToDuplicate(tmp00);
3947 DAInt cellsToModifyConn0(tmp11);
3948 DAInt cellsToModifyConn1(tmp22);
3949 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3950 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3951 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3952 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3953 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3954 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3955 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3956 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3957 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3958 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3959 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3960 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3961 DAInt grpIds=getGroupArr(-1,grpNameM1);
3962 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3963 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3964 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3965 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3966 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3967 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3968 m0->setCoords(tmp0->getCoords());
3969 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3970 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3971 m1->setCoords(m0->getCoords());
3972 _coords=m0->getCoords(); _coords->incrRef();
3973 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3974 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3975 DataArrayInt * duplCells;
3976 m1->areCellsIncludedIn(m11, 0, duplCells);
3977 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3978 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3979 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3980 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3981 DAInt szOfCellGrpOfSameType(tmp00);
3982 DAInt idInMsOfCellGrpOfSameType(tmp11);
3984 newm1->setName(getName());
3985 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3987 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3988 DAInt newFam=DataArrayInt::New();
3989 newFam->alloc(newm1->getNumberOfCells(),1);
3990 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3991 // Positive ID for family of nodes, negative for all the rest.
3993 if (m1->getMeshDimension() == 0)
3994 idd=getMaxFamilyId()+1;
3996 idd=getMinFamilyId()-1;
3997 int globStart=0,start=0,end,globEnd;
3998 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3999 for(int i=0;i<nbOfChunks;i++)
4001 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
4002 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
4004 end=start+szOfCellGrpOfSameType->getIJ(i,0);
4005 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
4006 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
4011 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
4015 newm1->setCoords(getCoords());
4016 setMeshAtLevel(-1,newm1);
4017 setFamilyFieldArr(-1,newFam);
4018 std::string grpName2(grpNameM1); grpName2+="_dup";
4019 addFamily(grpName2,idd);
4020 addFamilyOnGrp(grpName2,grpName2);
4025 int newNbOfNodes=getCoords()->getNumberOfTuples();
4026 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
4027 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4028 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4032 _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
4034 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4035 it != _ms.end(); it++)
4038 (*it)->_rev_num = 0;
4040 nodesDuplicated=nodeIdsToDuplicate.retn();
4041 cellsModified=cellsToModifyConn0.retn();
4042 cellsNotModified=cellsToModifyConn1.retn();
4045 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4046 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4049 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4050 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4051 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4053 * \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.
4054 * 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.
4056 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4058 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4059 std::vector<int> levs=getNonEmptyLevels();
4061 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4062 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4065 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4067 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4068 std::vector<int> code1=m->getDistributionOfTypes();
4069 end=PutInThirdComponentOfCodeOffset(code1,start);
4070 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4071 bool hasChanged=m->unPolyze();
4072 DataArrayInt *fake=0;
4073 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4074 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4076 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4079 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4080 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4082 MCAuto<DataArrayInt> famField2,numField2;
4083 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4084 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4085 setMeshAtLevel(*it,m);
4086 std::vector<int> code2=m->getDistributionOfTypes();
4087 end=PutInThirdComponentOfCodeOffset(code2,start);
4088 newCode.insert(newCode.end(),code2.begin(),code2.end());
4090 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4094 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4095 setFamilyFieldArr(*it,newFamField);
4099 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4100 setRenumFieldArr(*it,newNumField);
4105 newCode.insert(newCode.end(),code1.begin(),code1.end());
4111 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4112 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4113 o2nRenumCell=o2nRenumCellRet.retn();
4118 /*! \cond HIDDEN_ITEMS */
4119 struct MEDLoaderAccVisit1
4121 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4122 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4123 int _new_nb_of_nodes;
4128 * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
4129 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4130 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4131 * -1 values in returned array means that the corresponding old node is no more used.
4133 * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
4134 * is modified in \a this.
4135 * \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
4138 DataArrayInt *MEDFileUMesh::zipCoords()
4140 const DataArrayDouble *coo(getCoords());
4142 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4143 int nbOfNodes(coo->getNumberOfTuples());
4144 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4145 std::vector<int> neLevs(getNonEmptyLevels());
4146 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4148 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4149 if(zeLev->isMeshStoredSplitByType())
4151 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4152 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4154 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4158 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4159 mesh->computeNodeIdsAlg(nodeIdsInUse);
4162 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4163 if(nbrOfNodesInUse==nbOfNodes)
4164 return 0;//no need to update _part_coords
4165 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4166 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4167 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4168 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4169 MCAuto<DataArrayInt> newFamCoords;
4170 MCAuto<DataArrayAsciiChar> newNameCoords;
4171 if((const DataArrayInt *)_fam_coords)
4172 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4173 MCAuto<DataArrayInt> newNumCoords,newGlobalNumCoords;
4174 if(_num_coords.isNotNull())
4175 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4176 if(_global_num_coords.isNotNull())
4177 newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4178 if(_name_coords.isNotNull())
4179 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4180 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
4181 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4183 if((MEDFileUMeshSplitL1*)*it)
4185 (*it)->renumberNodesInConn(ret->begin());
4186 (*it)->setCoords(_coords);
4189 // updates _part_coords
4190 const PartDefinition *pc(_part_coords);
4193 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4194 _part_coords=tmpPD->composeWith(pc);
4200 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4201 * The extraction of \a this is specified by the extractDef \a input map.
4202 * This map tells for each level of cells, the cells kept in the extraction.
4204 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4205 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4207 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4209 std::vector<int> levs(getNonEmptyLevels());
4210 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4211 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4214 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4215 if((*it).second.isNull())
4216 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4219 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4221 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4222 throw INTERP_KERNEL::Exception(oss.str());
4224 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4225 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4226 mPart->computeNodeIdsAlg(fetchedNodes);
4228 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4232 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4234 * \return - a new reference of MEDFileUMesh
4235 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4237 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4239 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4240 std::vector<int> levs(getNonEmptyLevels());
4241 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4244 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4245 if((*it).second.isNull())
4246 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4249 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4251 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4252 throw INTERP_KERNEL::Exception(oss.str());
4254 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4255 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4256 ret->setMeshAtLevel((*it).first,mPart);
4257 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4260 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4261 ret->setFamilyFieldArr((*it).first,famPart);
4265 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4266 ret->setFamilyFieldArr((*it).first,numPart);
4269 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4270 if(it2!=extractDef.end())
4272 const DataArrayDouble *coo(ret->getCoords());
4274 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4275 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4276 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4277 ret->setCoords(cooPart);
4278 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4281 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4282 ret->setFamilyFieldArr(1,famPart);
4286 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4287 ret->setFamilyFieldArr(1,numPart);
4289 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4293 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4294 m->renumberNodesInConn(o2nNodes->begin());
4295 ret->setMeshAtLevel((*it3).first,m);
4302 * This method performs an extrusion along a path defined by \a m1D.
4303 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4304 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4305 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4306 * This method scans all levels in \a this
4307 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4309 * \param [in] m1D - the mesh defining the extrusion path.
4310 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4311 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4313 * \sa MEDCouplingUMesh::buildExtrudedMesh
4315 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4318 if(getMeshDimension()!=2)
4319 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4320 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4321 m1D->checkConsistencyLight();
4322 if(m1D->getMeshDimension()!=1)
4323 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4324 int nbRep(m1D->getNumberOfCells());
4325 std::vector<int> levs(getNonEmptyLevels());
4326 std::vector<std::string> grps(getGroupsNames());
4327 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4328 DataArrayDouble *coords(0);
4329 std::size_t nbOfLevsOut(levs.size()+1);
4330 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4331 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4333 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4334 item=item->clone(false);
4335 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4336 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4337 tmp->changeSpaceDimension(3+(*lev),0.);
4338 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4339 zeList.push_back(elt);
4341 coords=elt->getCoords();
4344 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4345 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4347 (*it)->setName(getName());
4348 (*it)->setCoords(coords);
4350 for(std::size_t ii=0;ii!=zeList.size();ii++)
4353 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4356 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4357 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4358 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4359 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4360 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4361 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4362 std::vector<const MEDCouplingUMesh *> elts(3);
4363 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4364 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4365 elt->setName(getName());
4368 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4369 ret->setMeshAtLevel(lev,elt);
4371 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4372 endLev=endLev->clone(false); endLev->setCoords(coords);
4373 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4374 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4375 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4376 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4377 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4378 endLev->setName(getName());
4379 ret->setMeshAtLevel(levs.back()-1,endLev);
4381 for(std::size_t ii=0;ii!=zeList.size();ii++)
4384 std::vector< MCAuto<DataArrayInt> > outGrps;
4385 std::vector< const DataArrayInt * > outGrps2;
4388 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4390 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4391 if(!grpArr->empty())
4393 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4394 int offset0(zeList[ii]->getNumberOfCells());
4395 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4396 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4397 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4398 grpArr2->setName(oss.str());
4399 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4400 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4401 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4402 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4407 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4409 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4410 if(!grpArr->empty())
4412 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4413 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4414 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4415 for(int iii=0;iii<nbRep;iii++)
4417 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4418 grpArrs2[iii]=grpArrs[iii];
4420 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4421 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4422 std::ostringstream grpName; grpName << *grp << "_extruded";
4423 grpArrExt->setName(grpName.str());
4424 outGrps.push_back(grpArrExt);
4425 outGrps2.push_back(grpArrExt);
4428 ret->setGroupsAtLevel(lev,outGrps2);
4430 std::vector< MCAuto<DataArrayInt> > outGrps;
4431 std::vector< const DataArrayInt * > outGrps2;
4432 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4434 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4435 if(grpArr1->empty())
4437 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4438 std::ostringstream grpName; grpName << *grp << "_top";
4439 grpArr2->setName(grpName.str());
4440 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4441 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4442 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4444 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4449 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4450 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4451 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4453 * \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
4454 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4455 * \param [in] eps - detection threshold for coordinates.
4456 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4458 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4460 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4463 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4464 int initialNbNodes(getNumberOfNodes());
4465 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4466 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4468 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4470 DataArrayDouble *zeCoords(m0->getCoords());
4471 ret->setMeshAtLevel(0,m0);
4472 std::vector<int> levs(getNonEmptyLevels());
4473 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4476 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4477 ret->setFamilyFieldArr(0,famFieldCpy);
4479 famField=getFamilyFieldAtLevel(1);
4482 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4483 fam->fillWithZero();
4484 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4485 ret->setFamilyFieldArr(1,fam);
4487 ret->copyFamGrpMapsFrom(*this);
4488 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4489 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4493 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4494 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4495 if(m1->getMeshDimension()!=0)
4498 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4499 }//kill unused notUsed var
4500 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4502 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4503 MCAuto<DataArrayInt> bSafe(b);
4506 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4507 throw INTERP_KERNEL::Exception(oss.str().c_str());
4509 b->applyLin(1,initialNbNodes);
4510 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4511 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4512 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4513 m1->renumberNodesInConn(renum->begin());
4515 m1->setCoords(zeCoords);
4516 ret->setMeshAtLevel(*lev,m1);
4517 famField=getFamilyFieldAtLevel(*lev);
4520 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4521 ret->setFamilyFieldArr(*lev,famFieldCpy);
4528 * This method converts all quadratic cells in \a this into linear cells.
4529 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4530 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4532 * \param [in] eps - detection threshold for coordinates.
4533 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4535 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4537 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4540 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4541 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4542 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4543 m0->convertQuadraticCellsToLinear();
4545 DataArrayDouble *zeCoords(m0->getCoords());
4546 ret->setMeshAtLevel(0,m0);
4547 std::vector<int> levs(getNonEmptyLevels());
4548 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4551 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4552 ret->setFamilyFieldArr(0,famFieldCpy);
4554 famField=getFamilyFieldAtLevel(1);
4557 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4558 ret->setFamilyFieldArr(1,fam);
4560 ret->copyFamGrpMapsFrom(*this);
4561 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4565 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4566 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4567 m1->convertQuadraticCellsToLinear();
4570 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4571 MCAuto<DataArrayInt> bSafe(b);
4574 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4575 throw INTERP_KERNEL::Exception(oss.str().c_str());
4577 m1->renumberNodesInConn(b->begin());
4578 m1->setCoords(zeCoords);
4579 ret->setMeshAtLevel(*lev,m1);
4580 famField=getFamilyFieldAtLevel(*lev);
4583 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4584 ret->setFamilyFieldArr(*lev,famFieldCpy);
4591 * Computes the symmetry of \a this.
4592 * \return a new object.
4594 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4596 MCAuto<MEDFileUMesh> ret(deepCopy());
4597 DataArrayDouble *myCoo(getCoords());
4600 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4601 ret->setCoordsForced(newCoo);
4606 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4609 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4610 std::size_t sz(meshes.size()),i(0);
4611 std::vector<const DataArrayDouble *> coos(sz);
4612 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4613 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4616 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4617 coos[i]=(*it)->getCoords();
4618 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4619 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4621 const MEDFileUMesh *ref(meshes[0]);
4622 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4623 std::vector<int> levs(ref->getNonEmptyLevels());
4624 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4625 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4626 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4627 std::map<std::string,int> map1;
4628 std::map<std::string, std::vector<std::string> > map2;
4629 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4631 if((*it)->getSpaceDimension()!=spaceDim)
4632 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4633 if((*it)->getMeshDimension()!=meshDim)
4634 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4635 if((*it)->getNonEmptyLevels()!=levs)
4636 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4637 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4639 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4640 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4641 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4642 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4644 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4645 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4646 map1[(*it3).first]=(*it3).second;
4647 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4648 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4649 map2[(*it4).first]=(*it4).second;
4651 // Easy part : nodes
4652 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4653 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4654 ret->setCoords(coo);
4655 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4657 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4658 ret->setFamilyFieldArr(1,fam_coo);
4660 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4662 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4663 ret->setRenumFieldArr(1,num_coo);
4666 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4668 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4669 if(it2==m_mesh.end())
4670 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4671 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4672 mesh->setCoords(coo); mesh->setName(ref->getName());
4673 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4674 ret->setMeshAtLevel(*it,mesh);
4675 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4676 if(it3!=m_fam.end())
4678 const std::vector<const DataArrayInt *>& fams((*it3).second);
4679 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4681 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4682 famm->renumberInPlace(renum->begin());
4683 ret->setFamilyFieldArr(*it,famm);
4686 if(it4!=m_renum.end())
4688 const std::vector<const DataArrayInt *>& renums((*it4).second);
4689 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4691 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4692 renumm->renumberInPlace(renum->begin());
4693 ret->setRenumFieldArr(*it,renumm);
4698 ret->setFamilyInfo(map1);
4699 ret->setGroupInfo(map2);
4700 ret->setName(ref->getName());
4704 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4706 if(getMeshDimension()!=3)
4707 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4708 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4709 if(m3D.isNull() || m2D.isNull())
4710 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4711 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4712 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4716 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4718 clearNonDiscrAttributes();
4719 forceComputationOfParts();
4720 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4721 std::vector<int> layer0;
4722 layer0.push_back(getAxisType());//0 i
4723 layer0.push_back(_order); //1 i
4724 layer0.push_back(_iteration);//2 i
4725 layer0.push_back(getSpaceDimension());//3 i
4726 tinyDouble.push_back(_time);//0 d
4727 tinyStr.push_back(_name);//0 s
4728 tinyStr.push_back(_desc_name);//1 s
4729 for(int i=0;i<getSpaceDimension();i++)
4730 tinyStr.push_back(_coords->getInfoOnComponent(i));
4731 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4732 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4734 tinyStr.push_back((*it).first);
4735 layer0.push_back((*it).second);
4737 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4738 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4740 layer0.push_back((int)(*it0).second.size());
4741 tinyStr.push_back((*it0).first);
4742 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4743 tinyStr.push_back(*it1);
4745 // sizeof(layer0)==4+aa+1+bb layer#0
4746 bigArrayD=_coords;// 0 bd
4747 bigArraysI.push_back(_fam_coords);// 0 bi
4748 bigArraysI.push_back(_num_coords);// 1 bi
4749 const PartDefinition *pd(_part_coords);
4751 layer0.push_back(-1);
4754 std::vector<int> tmp0;
4755 pd->serialize(tmp0,bigArraysI);
4756 tinyInt.push_back(tmp0.size());
4757 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4760 std::vector<int> layer1;
4761 std::vector<int> levs(getNonEmptyLevels());
4762 layer1.push_back((int)levs.size());// 0 i <- key
4763 layer1.insert(layer1.end(),levs.begin(),levs.end());
4764 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4766 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4767 lev->serialize(layer1,bigArraysI);
4769 // put layers all together.
4770 tinyInt.push_back(layer0.size());
4771 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4772 tinyInt.push_back(layer1.size());
4773 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4776 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4777 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4779 int sz0(tinyInt[0]);
4780 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4781 int sz1(tinyInt[sz0+1]);
4782 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4784 std::reverse(layer0.begin(),layer0.end());
4785 std::reverse(layer1.begin(),layer1.end());
4786 std::reverse(tinyDouble.begin(),tinyDouble.end());
4787 std::reverse(tinyStr.begin(),tinyStr.end());
4788 std::reverse(bigArraysI.begin(),bigArraysI.end());
4790 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4791 _order=layer0.back(); layer0.pop_back();
4792 _iteration=layer0.back(); layer0.pop_back();
4793 int spaceDim(layer0.back()); layer0.pop_back();
4794 _time=tinyDouble.back(); tinyDouble.pop_back();
4795 _name=tinyStr.back(); tinyStr.pop_back();
4796 _desc_name=tinyStr.back(); tinyStr.pop_back();
4797 _coords=bigArrayD; _coords->rearrange(spaceDim);
4798 for(int i=0;i<spaceDim;i++)
4800 _coords->setInfoOnComponent(i,tinyStr.back());
4803 int nbOfFams(layer0.back()); layer0.pop_back();
4805 for(int i=0;i<nbOfFams;i++)
4807 _families[tinyStr.back()]=layer0.back();
4808 tinyStr.pop_back(); layer0.pop_back();
4810 int nbGroups(layer0.back()); layer0.pop_back();
4812 for(int i=0;i<nbGroups;i++)
4814 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4815 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4816 std::vector<std::string> fams(nbOfFamsOnGrp);
4817 for(int j=0;j<nbOfFamsOnGrp;j++)
4819 fams[j]=tinyStr.back(); tinyStr.pop_back();
4821 _groups[grpName]=fams;
4823 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4824 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4826 int isPd(layer0.back()); layer0.pop_back();
4829 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4830 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4831 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4834 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4836 int nbLevs(layer1.back()); layer1.pop_back();
4837 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4839 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4840 _ms.resize(maxLev+1);
4841 for(int i=0;i<nbLevs;i++)
4845 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4850 * Adds a group of nodes to \a this mesh.
4851 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4852 * The ids should be sorted and different each other (MED file norm).
4854 * \warning this method can alter default "FAMILLE_ZERO" family.
4855 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4857 * \throw If the node coordinates array is not set.
4858 * \throw If \a ids == \c NULL.
4859 * \throw If \a ids->getName() == "".
4860 * \throw If \a ids does not respect the MED file norm.
4861 * \throw If a group with name \a ids->getName() already exists.
4863 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4865 const DataArrayDouble *coords(_coords);
4867 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4868 int nbOfNodes(coords->getNumberOfTuples());
4869 if(!((DataArrayInt *)_fam_coords))
4870 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4872 addGroupUnderground(true,ids,_fam_coords);
4876 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4878 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4879 * The ids should be sorted and different each other (MED file norm).
4881 * \warning this method can alter default "FAMILLE_ZERO" family.
4882 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4884 * \throw If the node coordinates array is not set.
4885 * \throw If \a ids == \c NULL.
4886 * \throw If \a ids->getName() == "".
4887 * \throw If \a ids does not respect the MED file norm.
4888 * \throw If a group with name \a ids->getName() already exists.
4890 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4892 std::vector<int> levs(getNonEmptyLevelsExt());
4893 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4895 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4896 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4898 if(meshDimRelToMaxExt==1)
4899 { addNodeGroup(ids); return ; }
4900 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4901 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4902 addGroupUnderground(false,ids,fam);
4906 * Changes a name of a family specified by its id.
4907 * \param [in] id - the id of the family of interest.
4908 * \param [in] newFamName - the new family name.
4909 * \throw If no family with the given \a id exists.
4911 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4913 std::string oldName=getFamilyNameGivenId(id);
4914 _families.erase(oldName);
4915 _families[newFamName]=id;
4919 * Removes a mesh of a given dimension.
4920 * \param [in] meshDimRelToMax - the relative dimension of interest.
4921 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4923 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4925 std::vector<int> levSet=getNonEmptyLevels();
4926 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4927 if(it==levSet.end())
4928 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4929 int pos=(-meshDimRelToMax);
4934 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4935 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4936 * \param [in] m - the new mesh to set.
4937 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4939 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4940 * another node coordinates array.
4941 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4942 * to the existing meshes of other levels of \a this mesh.
4944 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4946 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4947 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4951 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4952 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4953 * \param [in] m - the new mesh to set.
4954 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4955 * writing \a this mesh in a MED file.
4956 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4958 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4959 * another node coordinates array.
4960 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4961 * to the existing meshes of other levels of \a this mesh.
4963 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4965 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4966 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4969 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4971 dealWithTinyInfo(m);
4972 std::vector<int> levSet=getNonEmptyLevels();
4973 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4975 if((DataArrayDouble *)_coords==0)
4977 DataArrayDouble *c=m->getCoords();
4982 if(m->getCoords()!=_coords)
4983 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4984 int sz=(-meshDimRelToMax)+1;
4985 if(sz>=(int)_ms.size())
4987 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4991 return _ms[-meshDimRelToMax];
4995 * This method allows to set at once the content of different levels in \a this.
4996 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4998 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4999 * \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.
5000 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
5002 * \throw If \a there is a null pointer in \a ms.
5003 * \sa MEDFileUMesh::setMeshAtLevel
5005 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5009 const MEDCouplingUMesh *mRef=ms[0];
5011 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
5012 std::string name(mRef->getName());
5013 const DataArrayDouble *coo(mRef->getCoords());
5016 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5018 const MEDCouplingUMesh *cur(*it);
5020 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
5021 if(coo!=cur->getCoords())
5022 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
5023 int mdim=cur->getMeshDimension();
5024 zeDim=std::max(zeDim,mdim);
5025 if(s.find(mdim)!=s.end())
5026 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5028 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5030 int mdim=(*it)->getMeshDimension();
5031 setName((*it)->getName());
5032 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5038 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5039 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5040 * The given meshes must share the same node coordinates array.
5041 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5042 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5043 * create in \a this mesh.
5044 * \throw If \a ms is empty.
5045 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5046 * to the existing meshes of other levels of \a this mesh.
5047 * \throw If the meshes in \a ms do not share the same node coordinates array.
5048 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5049 * of the given meshes.
5050 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5051 * \throw If names of some meshes in \a ms are equal.
5052 * \throw If \a ms includes a mesh with an empty name.
5054 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5057 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5058 int sz=(-meshDimRelToMax)+1;
5059 if(sz>=(int)_ms.size())
5061 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5062 DataArrayDouble *coo=checkMultiMesh(ms);
5063 if((DataArrayDouble *)_coords==0)
5069 if((DataArrayDouble *)_coords!=coo)
5070 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5071 std::vector<DataArrayInt *> corr;
5072 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5073 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5074 setMeshAtLevel(meshDimRelToMax,m,renum);
5075 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5076 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5080 * Creates groups at a given level in \a this mesh from a sequence of
5081 * meshes each representing a group.
5082 * The given meshes must share the same node coordinates array.
5083 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5084 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5085 * create in \a this mesh.
5086 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5088 * \throw If \a ms is empty.
5089 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5090 * to the existing meshes of other levels of \a this mesh.
5091 * \throw If the meshes in \a ms do not share the same node coordinates array.
5092 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5093 * of the given meshes.
5094 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5095 * \throw If names of some meshes in \a ms are equal.
5096 * \throw If \a ms includes a mesh with an empty name.
5098 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5101 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5102 int sz=(-meshDimRelToMax)+1;
5103 if(sz>=(int)_ms.size())
5105 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5106 DataArrayDouble *coo=checkMultiMesh(ms);
5107 if((DataArrayDouble *)_coords==0)
5113 if((DataArrayDouble *)_coords!=coo)
5114 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5115 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5116 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5118 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5120 DataArrayInt *arr=0;
5121 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5125 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5126 throw INTERP_KERNEL::Exception(oss.str().c_str());
5129 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5130 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5133 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5135 const DataArrayDouble *ret=ms[0]->getCoords();
5136 int mdim=ms[0]->getMeshDimension();
5137 for(unsigned int i=1;i<ms.size();i++)
5139 ms[i]->checkConsistencyLight();
5140 if(ms[i]->getCoords()!=ret)
5141 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5142 if(ms[i]->getMeshDimension()!=mdim)
5143 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5145 return const_cast<DataArrayDouble *>(ret);
5149 * Sets the family field of a given relative dimension.
5150 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5151 * the family field is set.
5152 * \param [in] famArr - the array of the family field.
5153 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5154 * \throw If \a famArr has an invalid size.
5156 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5158 if(meshDimRelToMaxExt==1)
5165 DataArrayDouble *coo(_coords);
5167 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5168 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5173 if(meshDimRelToMaxExt>1)
5174 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5175 int traducedRk=-meshDimRelToMaxExt;
5176 if(traducedRk>=(int)_ms.size())
5177 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5178 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5179 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5180 return _ms[traducedRk]->setFamilyArr(famArr);
5184 * Sets the optional numbers of mesh entities of a given dimension.
5185 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5186 * \param [in] renumArr - the array of the numbers.
5187 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5188 * \throw If \a renumArr has an invalid size.
5190 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5192 if(meshDimRelToMaxExt==1)
5196 _num_coords.nullify();
5197 _rev_num_coords.nullify();
5200 DataArrayDouble *coo(_coords);
5202 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5203 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5204 renumArr->incrRef();
5205 _num_coords=renumArr;
5209 if(meshDimRelToMaxExt>1)
5210 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5211 int traducedRk=-meshDimRelToMaxExt;
5212 if(traducedRk>=(int)_ms.size())
5213 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5214 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5215 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5216 return _ms[traducedRk]->setRenumArr(renumArr);
5220 * Sets the optional names of mesh entities of a given dimension.
5221 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5222 * \param [in] nameArr - the array of the names.
5223 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5224 * \throw If \a nameArr has an invalid size.
5226 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5228 if(meshDimRelToMaxExt==1)
5235 DataArrayDouble *coo(_coords);
5237 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5238 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5240 _name_coords=nameArr;
5243 if(meshDimRelToMaxExt>1)
5244 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5245 int traducedRk=-meshDimRelToMaxExt;
5246 if(traducedRk>=(int)_ms.size())
5247 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5248 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5249 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5250 return _ms[traducedRk]->setNameArr(nameArr);
5253 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5255 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5256 if((const MEDFileUMeshSplitL1 *)(*it))
5257 (*it)->synchronizeTinyInfo(*this);
5261 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5263 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5265 DataArrayInt *arr=_fam_coords;
5267 arr->changeValue(oldId,newId);
5268 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5270 MEDFileUMeshSplitL1 *sp=(*it);
5273 sp->changeFamilyIdArr(oldId,newId);
5278 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5280 std::list< MCAuto<DataArrayInt> > ret;
5281 const DataArrayInt *da(_fam_coords);
5283 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5284 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5286 const MEDFileUMeshSplitL1 *elt(*it);
5289 da=elt->getFamilyField();
5291 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5297 void MEDFileUMesh::computeRevNum() const
5299 if(_num_coords.isNotNull())
5302 int maxValue=_num_coords->getMaxValue(pos);
5303 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5307 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5309 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5312 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5314 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5315 ret.push_back((const DataArrayInt *)_fam_nodes);
5316 ret.push_back((const DataArrayInt *)_num_nodes);
5317 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5318 ret.push_back((const DataArrayInt *)_fam_cells);
5319 ret.push_back((const DataArrayInt *)_num_cells);
5320 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5321 ret.push_back((const DataArrayInt *)_fam_faces);
5322 ret.push_back((const DataArrayInt *)_num_faces);
5323 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5324 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5325 ret.push_back((const DataArrayInt *)_rev_num_cells);
5326 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5330 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5332 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5333 if((const DataArrayInt *)_fam_nodes)
5335 int val=_fam_nodes->getMaxValue(tmp);
5336 ret=std::max(ret,std::abs(val));
5338 if((const DataArrayInt *)_fam_cells)
5340 int val=_fam_cells->getMaxValue(tmp);
5341 ret=std::max(ret,std::abs(val));
5343 if((const DataArrayInt *)_fam_faces)
5345 int val=_fam_faces->getMaxValue(tmp);
5346 ret=std::max(ret,std::abs(val));
5351 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5353 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5354 if((const DataArrayInt *)_fam_nodes)
5356 int val=_fam_nodes->getMaxValue(tmp);
5357 ret=std::max(ret,val);
5359 if((const DataArrayInt *)_fam_cells)
5361 int val=_fam_cells->getMaxValue(tmp);
5362 ret=std::max(ret,val);
5364 if((const DataArrayInt *)_fam_faces)
5366 int val=_fam_faces->getMaxValue(tmp);
5367 ret=std::max(ret,val);
5372 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5374 int ret=std::numeric_limits<int>::max(),tmp=-1;
5375 if((const DataArrayInt *)_fam_nodes)
5377 int val=_fam_nodes->getMinValue(tmp);
5378 ret=std::min(ret,val);
5380 if((const DataArrayInt *)_fam_cells)
5382 int val=_fam_cells->getMinValue(tmp);
5383 ret=std::min(ret,val);
5385 if((const DataArrayInt *)_fam_faces)
5387 int val=_fam_faces->getMinValue(tmp);
5388 ret=std::min(ret,val);
5393 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5395 if(!MEDFileMesh::isEqual(other,eps,what))
5397 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5400 what="Mesh types differ ! This is structured and other is NOT !";
5403 const DataArrayInt *famc1=_fam_nodes;
5404 const DataArrayInt *famc2=otherC->_fam_nodes;
5405 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5407 what="Mismatch of families arr on nodes ! One is defined and not other !";
5412 bool ret=famc1->isEqual(*famc2);
5415 what="Families arr on nodes differ !";
5420 famc2=otherC->_fam_cells;
5421 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5423 what="Mismatch of families arr on cells ! One is defined and not other !";
5428 bool ret=famc1->isEqual(*famc2);
5431 what="Families arr on cells differ !";
5436 famc2=otherC->_fam_faces;
5437 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5439 what="Mismatch of families arr on faces ! One is defined and not other !";
5444 bool ret=famc1->isEqual(*famc2);
5447 what="Families arr on faces differ !";
5452 famc2=otherC->_num_nodes;
5453 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5455 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5460 bool ret=famc1->isEqual(*famc2);
5463 what="Numbering arr on nodes differ !";
5468 famc2=otherC->_num_cells;
5469 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5471 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5476 bool ret=famc1->isEqual(*famc2);
5479 what="Numbering arr on cells differ !";
5484 famc2=otherC->_num_faces;
5485 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5487 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5492 bool ret=famc1->isEqual(*famc2);
5495 what="Numbering arr on faces differ !";
5499 const DataArrayAsciiChar *d1=_names_cells;
5500 const DataArrayAsciiChar *d2=otherC->_names_cells;
5501 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5503 what="Mismatch of naming arr on cells ! One is defined and not other !";
5508 bool ret=d1->isEqual(*d2);
5511 what="Naming arr on cells differ !";
5516 d2=otherC->_names_faces;
5517 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5519 what="Mismatch of naming arr on faces ! One is defined and not other !";
5524 bool ret=d1->isEqual(*d2);
5527 what="Naming arr on faces differ !";
5532 d2=otherC->_names_nodes;
5533 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5535 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5540 bool ret=d1->isEqual(*d2);
5543 what="Naming arr on nodes differ !";
5550 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5552 MEDFileMesh::clearNonDiscrAttributes();
5553 const DataArrayInt *tmp=_fam_nodes;
5555 (const_cast<DataArrayInt *>(tmp))->setName("");
5558 (const_cast<DataArrayInt *>(tmp))->setName("");
5561 (const_cast<DataArrayInt *>(tmp))->setName("");
5564 (const_cast<DataArrayInt *>(tmp))->setName("");
5567 (const_cast<DataArrayInt *>(tmp))->setName("");
5570 (const_cast<DataArrayInt *>(tmp))->setName("");
5574 * Returns ids of mesh entities contained in given families of a given dimension.
5575 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5577 * \param [in] fams - the names of the families of interest.
5578 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5579 * returned instead of ids.
5580 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5581 * numbers, if available and required, of mesh entities of the families. The caller
5582 * is to delete this array using decrRef() as it is no more needed.
5583 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5585 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5587 std::vector<int> famIds(getFamiliesIds(fams));
5588 switch(meshDimRelToMaxExt)
5592 if((const DataArrayInt *)_fam_nodes)
5594 MCAuto<DataArrayInt> da;
5596 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5598 da=_fam_nodes->findIdsEqualList(0,0);
5600 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5605 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5610 if((const DataArrayInt *)_fam_cells)
5612 MCAuto<DataArrayInt> da;
5614 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5616 da=_fam_cells->findIdsEqualList(0,0);
5618 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5623 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5628 if((const DataArrayInt *)_fam_faces)
5630 MCAuto<DataArrayInt> da;
5632 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5634 da=_fam_faces->findIdsEqualList(0,0);
5636 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5641 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5645 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5647 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5651 * Sets the family field of a given relative dimension.
5652 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5653 * the family field is set.
5654 * \param [in] famArr - the array of the family field.
5655 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5656 * \throw If \a famArr has an invalid size.
5657 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5659 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5661 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5663 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5664 switch(meshDimRelToMaxExt)
5668 int nbCells(mesh->getNumberOfCells());
5670 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5676 int nbNodes(mesh->getNumberOfNodes());
5678 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5684 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5686 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5691 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5698 * Sets the optional numbers of mesh entities of a given dimension.
5699 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5700 * \param [in] renumArr - the array of the numbers.
5701 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5702 * \throw If \a renumArr has an invalid size.
5703 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5705 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5707 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5709 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5710 switch(meshDimRelToMaxExt)
5714 int nbCells=mesh->getNumberOfCells();
5715 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5716 _num_cells=renumArr;
5721 int nbNodes=mesh->getNumberOfNodes();
5722 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5723 _num_nodes=renumArr;
5728 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5729 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5730 _num_faces=renumArr;
5734 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5737 renumArr->incrRef();
5741 * Sets the optional names of mesh entities of a given dimension.
5742 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5743 * \param [in] nameArr - the array of the names.
5744 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5745 * \throw If \a nameArr has an invalid size.
5747 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5749 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5751 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5752 switch(meshDimRelToMaxExt)
5756 int nbCells=mesh->getNumberOfCells();
5757 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5758 _names_cells=nameArr;
5763 int nbNodes=mesh->getNumberOfNodes();
5764 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5765 _names_nodes=nameArr;
5770 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5771 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5772 _names_cells=nameArr;
5775 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5782 * Adds a group of nodes to \a this mesh.
5783 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5784 * The ids should be sorted and different each other (MED file norm).
5786 * \warning this method can alter default "FAMILLE_ZERO" family.
5787 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5789 * \throw If the node coordinates array is not set.
5790 * \throw If \a ids == \c NULL.
5791 * \throw If \a ids->getName() == "".
5792 * \throw If \a ids does not respect the MED file norm.
5793 * \throw If a group with name \a ids->getName() already exists.
5795 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5801 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5803 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5804 * The ids should be sorted and different each other (MED file norm).
5806 * \warning this method can alter default "FAMILLE_ZERO" family.
5807 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5809 * \throw If the node coordinates array is not set.
5810 * \throw If \a ids == \c NULL.
5811 * \throw If \a ids->getName() == "".
5812 * \throw If \a ids does not respect the MED file norm.
5813 * \throw If a group with name \a ids->getName() already exists.
5815 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5817 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5818 addGroupUnderground(false,ids,fam);
5823 * Returns the family field for mesh entities of a given dimension.
5824 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5825 * \return const DataArrayInt * - the family field. It is an array of ids of families
5826 * each mesh entity belongs to. It can be \c NULL.
5827 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5829 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5831 switch(meshDimRelToMaxExt)
5840 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5845 * Returns the family field for mesh entities of a given dimension.
5846 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5847 * \return const DataArrayInt * - the family field. It is an array of ids of families
5848 * each mesh entity belongs to. It can be \c NULL.
5849 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5851 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5853 switch(meshDimRelToMaxExt)
5862 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5867 * Returns the optional numbers of mesh entities of a given dimension.
5868 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5869 * \return const DataArrayInt * - the array of the entity numbers.
5870 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5871 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5873 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5875 switch(meshDimRelToMaxExt)
5884 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5889 * Returns the optional numbers of mesh entities of a given dimension transformed using
5890 * DataArrayInt::invertArrayN2O2O2N().
5891 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5892 * \return const DataArrayInt * - the array of the entity numbers transformed using
5893 * DataArrayInt::invertArrayN2O2O2N().
5894 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5895 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5897 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5899 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5900 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5901 if(meshDimRelToMaxExt==0)
5903 if((const DataArrayInt *)_num_cells)
5906 int maxValue=_num_cells->getMaxValue(pos);
5907 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5908 return _rev_num_cells;
5911 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5915 if((const DataArrayInt *)_num_nodes)
5918 int maxValue=_num_nodes->getMaxValue(pos);
5919 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5920 return _rev_num_nodes;
5923 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5927 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5929 switch(meshDimRelToMaxExt)
5932 return _names_cells;
5934 return _names_nodes;
5936 return _names_faces;
5938 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5943 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5944 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5946 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5948 std::vector<int> ret(1);
5953 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5954 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5956 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5958 std::vector<int> ret(2);
5964 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5966 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5968 std::vector<int> ret;
5969 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5980 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5982 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5984 std::vector<int> ret;
5985 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5996 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5998 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
6000 std::vector<int> ret;
6001 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
6012 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
6014 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
6016 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
6020 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
6022 DataArrayInt *arr=_fam_nodes;
6024 arr->changeValue(oldId,newId);
6027 arr->changeValue(oldId,newId);
6030 arr->changeValue(oldId,newId);
6033 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6035 std::list< MCAuto<DataArrayInt> > ret;
6036 const DataArrayInt *da(_fam_nodes);
6038 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6041 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6044 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6048 void MEDFileStructuredMesh::deepCpyAttributes()
6050 if((const DataArrayInt*)_fam_nodes)
6051 _fam_nodes=_fam_nodes->deepCopy();
6052 if((const DataArrayInt*)_num_nodes)
6053 _num_nodes=_num_nodes->deepCopy();
6054 if((const DataArrayAsciiChar*)_names_nodes)
6055 _names_nodes=_names_nodes->deepCopy();
6056 if((const DataArrayInt*)_fam_cells)
6057 _fam_cells=_fam_cells->deepCopy();
6058 if((const DataArrayInt*)_num_cells)
6059 _num_cells=_num_cells->deepCopy();
6060 if((const DataArrayAsciiChar*)_names_cells)
6061 _names_cells=_names_cells->deepCopy();
6062 if((const DataArrayInt*)_fam_faces)
6063 _fam_faces=_fam_faces->deepCopy();
6064 if((const DataArrayInt*)_num_faces)
6065 _num_faces=_num_faces->deepCopy();
6066 if((const DataArrayAsciiChar*)_names_faces)
6067 _names_faces=_names_faces->deepCopy();
6068 if((const DataArrayInt*)_rev_num_nodes)
6069 _rev_num_nodes=_rev_num_nodes->deepCopy();
6070 if((const DataArrayInt*)_rev_num_cells)
6071 _rev_num_cells=_rev_num_cells->deepCopy();
6075 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
6077 * \return a pointer to cartesian mesh that need to be managed by the caller.
6078 * \warning the returned pointer has to be managed by the caller.
6082 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6083 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6084 * \param [in] renum - it must be \c false.
6085 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6086 * delete using decrRef() as it is no more needed.
6088 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6092 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6093 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6094 switch(meshDimRelToMax)
6100 return const_cast<MEDCouplingStructuredMesh *>(m);
6105 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6106 buildMinusOneImplicitPartIfNeeded();
6107 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6113 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6117 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6119 std::vector<int> ret;
6120 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6121 if(famCells && famCells->presenceOfValue(ret))
6123 if(famFaces && famFaces->presenceOfValue(ret))
6128 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6130 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6131 const DataArrayInt *famNodes(_fam_nodes);
6132 if(famNodes && famNodes->presenceOfValue(ret))
6138 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6139 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6140 * \return int - the number of entities.
6141 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6143 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6145 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6147 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6148 switch(meshDimRelToMaxExt)
6151 return cmesh->getNumberOfCells();
6153 return cmesh->getNumberOfNodes();
6155 return cmesh->getNumberOfCellsOfSubLevelMesh();
6157 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6161 int MEDFileStructuredMesh::getNumberOfNodes() const
6163 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6165 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6166 return cmesh->getNumberOfNodes();
6169 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6171 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6173 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6174 switch(meshDimRelToMaxExt)
6177 return cmesh->getNumberOfCells();
6179 return cmesh->getNumberOfCellsOfSubLevelMesh();
6181 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6185 bool MEDFileStructuredMesh::hasImplicitPart() const
6191 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6193 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6195 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6196 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6199 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6200 if(cm.getReverseExtrudedType()!=gt)
6201 throw INTERP_KERNEL::Exception(MSG);
6202 buildImplicitPart();
6203 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6207 if(gt!=zeFaceMesh->getCellModelEnum())
6208 throw INTERP_KERNEL::Exception(MSG);
6209 return zeFaceMesh->getNumberOfCells();
6213 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6215 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6217 buildImplicitPart();
6220 void MEDFileStructuredMesh::buildImplicitPart() const
6222 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6224 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6225 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6228 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6230 _faces_if_necessary=0;
6234 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6235 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6237 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6239 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6242 return _faces_if_necessary;
6245 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6247 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6249 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6250 switch(meshDimRelToMax)
6254 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6259 int mdim(cmesh->getMeshDimension());
6261 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6262 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6266 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6270 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6272 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6275 return getNumberOfCellsAtLevel(0);
6278 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6280 if(st.getNumberOfItems()!=1)
6281 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 !");
6282 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6283 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6284 if(getNumberOfNodes()!=(int)nodesFetched.size())
6285 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6286 if(st[0].getPflName().empty())
6288 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6291 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6292 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6293 int sz(nodesFetched.size());
6294 for(const int *work=arr->begin();work!=arr->end();work++)
6296 std::vector<int> conn;
6297 cmesh->getNodeIdsOfCell(*work,conn);
6298 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6299 if(*it>=0 && *it<sz)
6300 nodesFetched[*it]=true;
6302 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6306 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6308 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6312 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6313 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6315 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6316 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6318 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6321 if(!mrs || mrs->isCellFamilyFieldReading())
6323 famCells=DataArrayInt::New();
6324 famCells->alloc(nbOfElt,1);
6325 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6328 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6331 if(!mrs || mrs->isCellNumFieldReading())
6333 numCells=DataArrayInt::New();
6334 numCells->alloc(nbOfElt,1);
6335 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6338 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6341 if(!mrs || mrs->isCellNameFieldReading())
6343 namesCells=DataArrayAsciiChar::New();
6344 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6345 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6346 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6351 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6353 setName(strm->getName());
6354 setDescription(strm->getDescription());
6355 setUnivName(strm->getUnivName());
6356 setIteration(strm->getIteration());
6357 setOrder(strm->getOrder());
6358 setTimeValue(strm->getTime());
6359 setTimeUnit(strm->getTimeUnit());
6360 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6361 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6362 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6365 if(!mrs || mrs->isNodeFamilyFieldReading())
6367 int nbNodes(getNumberOfNodes());
6369 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6370 _fam_nodes=DataArrayInt::New();
6371 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6372 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...
6373 _fam_nodes->fillWithZero();
6374 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6377 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6380 if(!mrs || mrs->isNodeNumFieldReading())
6382 _num_nodes=DataArrayInt::New();
6383 _num_nodes->alloc(nbOfElt,1);
6384 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6387 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6390 if(!mrs || mrs->isNodeNameFieldReading())
6392 _names_nodes=DataArrayAsciiChar::New();
6393 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6394 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6395 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6398 int meshDim(getStructuredMesh()->getMeshDimension());
6399 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6401 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6404 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6406 int meshDim(getStructuredMesh()->getMeshDimension());
6407 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6409 if((const DataArrayInt *)_fam_cells)
6410 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6411 if((const DataArrayInt *)_fam_faces)
6412 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6413 if((const DataArrayInt *)_fam_nodes)
6414 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6415 if((const DataArrayInt *)_num_cells)
6416 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6417 if((const DataArrayInt *)_num_faces)
6418 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6419 if((const DataArrayInt *)_num_nodes)
6420 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6421 if((const DataArrayAsciiChar *)_names_cells)
6423 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6425 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6426 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6427 throw INTERP_KERNEL::Exception(oss.str().c_str());
6429 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6431 if((const DataArrayAsciiChar *)_names_faces)
6433 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6435 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6436 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6437 throw INTERP_KERNEL::Exception(oss.str().c_str());
6439 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6441 if((const DataArrayAsciiChar *)_names_nodes)
6443 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6445 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6446 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6447 throw INTERP_KERNEL::Exception(oss.str().c_str());
6449 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6452 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6456 * Returns an empty instance of MEDFileCMesh.
6457 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6458 * mesh using decrRef() as it is no more needed.
6460 MEDFileCMesh *MEDFileCMesh::New()
6462 return new MEDFileCMesh;
6466 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6467 * file. The first mesh in the file is loaded.
6468 * \param [in] fileName - the name of MED file to read.
6469 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6470 * mesh using decrRef() as it is no more needed.
6471 * \throw If the file is not readable.
6472 * \throw If there is no meshes in the file.
6473 * \throw If the mesh in the file is not a Cartesian one.
6475 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6477 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6478 return New(fid,mrs);
6481 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6483 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6487 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6488 * file. The mesh to load is specified by its name and numbers of a time step and an
6490 * \param [in] fileName - the name of MED file to read.
6491 * \param [in] mName - the name of the mesh to read.
6492 * \param [in] dt - the number of a time step.
6493 * \param [in] it - the number of an iteration.
6494 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6495 * mesh using decrRef() as it is no more needed.
6496 * \throw If the file is not readable.
6497 * \throw If there is no mesh with given attributes in the file.
6498 * \throw If the mesh in the file is not a Cartesian one.
6500 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6502 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6503 return New(fid,mName,dt,it,mrs);
6506 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6508 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6511 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6513 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6516 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6518 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6519 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6524 * Returns the dimension on cells in \a this mesh.
6525 * \return int - the mesh dimension.
6526 * \throw If there are no cells in this mesh.
6528 int MEDFileCMesh::getMeshDimension() const
6530 if(!((const MEDCouplingCMesh*)_cmesh))
6531 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6532 return _cmesh->getMeshDimension();
6536 * Returns the dimension on nodes in \a this mesh.
6537 * \return int - the space dimension.
6538 * \throw If there are no cells in this mesh.
6540 int MEDFileCMesh::getSpaceDimension() const
6542 if(!((const MEDCouplingCMesh*)_cmesh))
6543 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6544 return _cmesh->getSpaceDimension();
6548 * Returns a string describing \a this mesh.
6549 * \return std::string - the mesh information string.
6551 std::string MEDFileCMesh::simpleRepr() const
6553 return MEDFileStructuredMesh::simpleRepr();
6557 * Returns a full textual description of \a this mesh.
6558 * \return std::string - the string holding the mesh description.
6560 std::string MEDFileCMesh::advancedRepr() const
6562 return simpleRepr();
6565 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6567 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6571 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6573 return new MEDFileCMesh;
6576 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6578 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6579 ret->deepCpyEquivalences(*this);
6580 if((const MEDCouplingCMesh*)_cmesh)
6581 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6582 ret->deepCpyAttributes();
6587 * Checks if \a this and another mesh are equal.
6588 * \param [in] other - the mesh to compare with.
6589 * \param [in] eps - a precision used to compare real values.
6590 * \param [in,out] what - the string returning description of unequal data.
6591 * \return bool - \c true if the meshes are equal, \c false, else.
6593 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6595 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6597 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6600 what="Mesh types differ ! This is cartesian and other is NOT !";
6603 clearNonDiscrAttributes();
6604 otherC->clearNonDiscrAttributes();
6605 const MEDCouplingCMesh *coo1=_cmesh;
6606 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6607 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6609 what="Mismatch of cartesian meshes ! One is defined and not other !";
6614 bool ret=coo1->isEqual(coo2,eps);
6617 what="cartesian meshes differ !";
6625 * Clears redundant attributes of incorporated data arrays.
6627 void MEDFileCMesh::clearNonDiscrAttributes() const
6629 MEDFileStructuredMesh::clearNonDiscrAttributes();
6630 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6633 MEDFileCMesh::MEDFileCMesh()
6637 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6640 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6642 catch(INTERP_KERNEL::Exception& e)
6647 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6649 MEDCoupling::MEDCouplingMeshType meshType;
6652 MEDCoupling::MEDCouplingAxisType axType;
6653 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6654 if(meshType!=CARTESIAN)
6656 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6657 throw INTERP_KERNEL::Exception(oss.str().c_str());
6659 MEDFileCMeshL2 loaderl2;
6660 loaderl2.loadAll(fid,mid,mName,dt,it);
6661 setAxisType(axType);
6662 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6665 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6669 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6670 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6672 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6674 synchronizeTinyInfoOnLeaves();
6678 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6680 synchronizeTinyInfoOnLeaves();
6685 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6686 * \param [in] m - the new MEDCouplingCMesh to refer to.
6687 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6690 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6692 dealWithTinyInfo(m);
6698 MEDFileMesh *MEDFileCMesh::cartesianize() const
6700 if(getAxisType()==AX_CART)
6703 return const_cast<MEDFileCMesh *>(this);
6707 const MEDCouplingCMesh *cmesh(getMesh());
6709 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6710 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6711 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6712 clmesh->setCoords(coords);
6713 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6714 ret->MEDFileStructuredMesh::operator=(*this);
6715 ret->setMesh(clmesh);
6716 ret->setAxisType(AX_CART);
6721 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6723 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6724 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6725 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6726 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6727 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6728 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6729 int spaceDim(_cmesh->getSpaceDimension());
6730 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6731 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6732 for(int i=0;i<spaceDim;i++)
6734 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6736 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6737 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
6738 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
6740 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6742 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6743 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6744 for(int i=0;i<spaceDim;i++)
6746 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6747 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6750 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6751 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6754 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6756 const MEDCouplingCMesh *cmesh=_cmesh;
6759 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6760 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6761 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6762 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6765 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6767 return new MEDFileCurveLinearMesh;
6770 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6772 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6775 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6777 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6778 return New(fid,mrs);
6781 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6783 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6784 return New(fid,mName,dt,it,mrs);
6787 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6789 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6792 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6794 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6797 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6799 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6800 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6804 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6806 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6810 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6812 return new MEDFileCurveLinearMesh;
6815 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6817 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6818 ret->deepCpyEquivalences(*this);
6819 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6820 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6821 ret->deepCpyAttributes();
6825 int MEDFileCurveLinearMesh::getMeshDimension() const
6827 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6828 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6829 return _clmesh->getMeshDimension();
6832 std::string MEDFileCurveLinearMesh::simpleRepr() const
6834 return MEDFileStructuredMesh::simpleRepr();
6837 std::string MEDFileCurveLinearMesh::advancedRepr() const
6839 return simpleRepr();
6842 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6844 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6846 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6849 what="Mesh types differ ! This is curve linear and other is NOT !";
6852 clearNonDiscrAttributes();
6853 otherC->clearNonDiscrAttributes();
6854 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6855 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6856 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6858 what="Mismatch of curve linear meshes ! One is defined and not other !";
6863 bool ret=coo1->isEqual(coo2,eps);
6866 what="curve linear meshes differ !";
6873 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6875 MEDFileStructuredMesh::clearNonDiscrAttributes();
6876 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6879 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6881 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6884 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6885 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6886 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6887 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6890 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6892 synchronizeTinyInfoOnLeaves();
6896 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6898 dealWithTinyInfo(m);
6904 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6906 if(getAxisType()==AX_CART)
6909 return const_cast<MEDFileCurveLinearMesh *>(this);
6913 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6915 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6916 const DataArrayDouble *coords(mesh->getCoords());
6918 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6919 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6920 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6921 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6922 mesh2->setCoords(coordsCart);
6923 ret->setMesh(mesh2);
6924 ret->setAxisType(AX_CART);
6929 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6931 synchronizeTinyInfoOnLeaves();
6935 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6939 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6942 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6944 catch(INTERP_KERNEL::Exception& e)
6949 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
6951 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6952 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6953 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6954 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6955 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6956 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6957 int spaceDim=_clmesh->getSpaceDimension();
6958 int meshDim=_clmesh->getMeshDimension();
6959 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6960 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6961 const DataArrayDouble *coords=_clmesh->getCoords();
6963 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
6964 for(int i=0;i<spaceDim;i++)
6966 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6968 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6969 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
6970 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
6972 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6974 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6975 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6976 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6977 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6979 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6981 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6982 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6985 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6987 MEDCoupling::MEDCouplingMeshType meshType;
6990 MEDCoupling::MEDCouplingAxisType axType;
6991 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6992 setAxisType(axType);
6993 if(meshType!=CURVE_LINEAR)
6995 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6996 throw INTERP_KERNEL::Exception(oss.str().c_str());
6998 MEDFileCLMeshL2 loaderl2;
6999 loaderl2.loadAll(fid,mid,mName,dt,it);
7000 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
7003 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
7006 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
7008 return new MEDFileMeshMultiTS;
7011 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
7013 return new MEDFileMeshMultiTS(fid);
7016 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
7018 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7022 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7024 return new MEDFileMeshMultiTS(fid,mName);
7027 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7029 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7030 return New(fid,mName);
7033 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7035 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7036 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7038 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7039 if((const MEDFileMesh *)*it)
7040 meshOneTs[i]=(*it)->deepCopy();
7041 ret->_mesh_one_ts=meshOneTs;
7045 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7047 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7050 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7052 std::vector<const BigMemoryObject *> ret;
7053 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7054 ret.push_back((const MEDFileMesh *)*it);
7058 std::string MEDFileMeshMultiTS::getName() const
7060 if(_mesh_one_ts.empty())
7061 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7062 return _mesh_one_ts[0]->getName();
7065 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7067 std::string oldName(getName());
7068 std::vector< std::pair<std::string,std::string> > v(1);
7069 v[0].first=oldName; v[0].second=newMeshName;
7073 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7076 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7078 MEDFileMesh *cur(*it);
7080 ret=cur->changeNames(modifTab) || ret;
7085 void MEDFileMeshMultiTS::cartesianizeMe()
7087 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7089 MEDFileMesh *cur(*it);
7092 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7098 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7100 if(_mesh_one_ts.empty())
7101 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7102 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7105 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7108 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7109 _mesh_one_ts.resize(1);
7110 mesh1TimeStep->incrRef();
7111 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7112 _mesh_one_ts[0]=mesh1TimeStep;
7115 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7117 if ( MEDFileMesh* m = getOneTimeStep() )
7118 return m->getJoints();
7123 * \brief Set Joints that are common to all time-stamps
7125 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7127 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7129 (*it)->setJoints( joints );
7133 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7135 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7136 if((*it).isNotNull())
7137 if((*it)->presenceOfStructureElements())
7142 void MEDFileMeshMultiTS::killStructureElements()
7144 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7145 if((*it).isNotNull())
7146 (*it)->killStructureElements();
7149 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7151 MEDFileJoints *joints(getJoints());
7152 bool jointsWritten(false);
7154 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7156 if ( jointsWritten )
7157 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7159 jointsWritten = true;
7161 (*it)->copyOptionsFrom(*this);
7162 (*it)->writeLL(fid);
7165 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7168 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7170 MEDFileJoints *joints(0);
7171 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7173 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7174 joints = getOneTimeStep()->getJoints();
7176 _mesh_one_ts.clear(); //for the moment to be improved
7177 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7180 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7184 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7187 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7190 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7191 throw INTERP_KERNEL::Exception(oss.str().c_str());
7194 MEDCoupling::MEDCouplingMeshType meshType;
7196 MEDCoupling::MEDCouplingAxisType dummy3;
7197 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7198 loadFromFile(fid,ms.front());
7200 catch(INTERP_KERNEL::Exception& e)
7205 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7208 loadFromFile(fid,mName);
7210 catch(INTERP_KERNEL::Exception& e)
7215 MEDFileMeshes *MEDFileMeshes::New()
7217 return new MEDFileMeshes;
7220 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7222 return new MEDFileMeshes(fid);
7225 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7227 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7231 void MEDFileMeshes::writeLL(med_idt fid) const
7233 checkConsistencyLight();
7234 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7236 (*it)->copyOptionsFrom(*this);
7237 (*it)->writeLL(fid);
7241 // MEDFileMeshes::writ checkConsistencyLight();
7243 int MEDFileMeshes::getNumberOfMeshes() const
7245 return _meshes.size();
7248 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7250 return new MEDFileMeshesIterator(this);
7253 /** Return a borrowed reference (caller is not responsible) */
7254 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7256 if(i<0 || i>=(int)_meshes.size())
7258 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7259 throw INTERP_KERNEL::Exception(oss.str().c_str());
7261 return _meshes[i]->getOneTimeStep();
7264 /** Return a borrowed reference (caller is not responsible) */
7265 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7267 std::vector<std::string> ms=getMeshesNames();
7268 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7271 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7272 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7273 throw INTERP_KERNEL::Exception(oss.str().c_str());
7275 return getMeshAtPos((int)std::distance(ms.begin(),it));
7278 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7280 std::vector<std::string> ret(_meshes.size());
7282 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7284 const MEDFileMeshMultiTS *f=(*it);
7287 ret[i]=f->getName();
7291 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7292 throw INTERP_KERNEL::Exception(oss.str().c_str());
7298 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7301 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7303 MEDFileMeshMultiTS *cur(*it);
7305 ret=cur->changeNames(modifTab) || ret;
7310 void MEDFileMeshes::cartesianizeMe()
7312 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7314 MEDFileMeshMultiTS *cur(*it);
7316 cur->cartesianizeMe();
7320 void MEDFileMeshes::resize(int newSize)
7322 _meshes.resize(newSize);
7325 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7328 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7329 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7330 elt->setOneTimeStep(mesh);
7331 _meshes.push_back(elt);
7334 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7337 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7338 if(i>=(int)_meshes.size())
7339 _meshes.resize(i+1);
7340 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7341 elt->setOneTimeStep(mesh);
7345 void MEDFileMeshes::destroyMeshAtPos(int i)
7347 if(i<0 || i>=(int)_meshes.size())
7349 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7350 throw INTERP_KERNEL::Exception(oss.str().c_str());
7352 _meshes.erase(_meshes.begin()+i);
7355 void MEDFileMeshes::loadFromFile(med_idt fid)
7357 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7359 _meshes.resize(ms.size());
7360 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7361 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7364 MEDFileMeshes::MEDFileMeshes()
7368 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7373 catch(INTERP_KERNEL::Exception& /*e*/)
7377 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7379 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7381 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7382 if((const MEDFileMeshMultiTS *)*it)
7383 meshes[i]=(*it)->deepCopy();
7384 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7385 ret->_meshes=meshes;
7389 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7391 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7394 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7396 std::vector<const BigMemoryObject *> ret;
7397 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7398 ret.push_back((const MEDFileMeshMultiTS *)*it);
7402 std::string MEDFileMeshes::simpleRepr() const
7404 std::ostringstream oss;
7405 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7406 simpleReprWithoutHeader(oss);
7410 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7412 int nbOfMeshes=getNumberOfMeshes();
7413 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7414 std::vector<std::string> mns=getMeshesNames();
7415 for(int i=0;i<nbOfMeshes;i++)
7416 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7419 void MEDFileMeshes::checkConsistencyLight() const
7421 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7423 std::set<std::string> s;
7424 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7426 const MEDFileMeshMultiTS *elt=(*it);
7429 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7430 throw INTERP_KERNEL::Exception(oss.str().c_str());
7432 std::size_t sz=s.size();
7433 s.insert(std::string((*it)->getName()));
7436 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7437 throw INTERP_KERNEL::Exception(oss.str().c_str());
7442 bool MEDFileMeshes::presenceOfStructureElements() const
7444 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7445 if((*it).isNotNull())
7446 if((*it)->presenceOfStructureElements())
7451 void MEDFileMeshes::killStructureElements()
7453 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7454 if((*it).isNotNull())
7455 (*it)->killStructureElements();
7458 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7463 _nb_iter=ms->getNumberOfMeshes();
7467 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7471 MEDFileMesh *MEDFileMeshesIterator::nextt()
7473 if(_iter_id<_nb_iter)
7475 MEDFileMeshes *ms(_ms);
7477 return ms->getMeshAtPos(_iter_id++);
7485 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7487 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7488 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7490 if(geoType==MED_NO_GEOTYPE)
7491 return INTERP_KERNEL::NORM_ERROR;
7492 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7493 throw INTERP_KERNEL::Exception(oss.str());
7495 return typmai2[std::distance(typmai,pos)];
7498 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7508 std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7509 throw INTERP_KERNEL::Exception(oss.str());