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 *)_rev_num_coords);
2361 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2362 ret.push_back((const PartDefinition *)_part_coords);
2363 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2364 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2365 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
2366 ret.push_back((const MEDFileEltStruct4Mesh *)*it);
2370 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2372 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2376 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2378 return new MEDFileUMesh;
2381 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2383 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2384 ret->deepCpyEquivalences(*this);
2385 if((const DataArrayDouble*)_coords)
2386 ret->_coords=_coords->deepCopy();
2387 if((const DataArrayInt*)_fam_coords)
2388 ret->_fam_coords=_fam_coords->deepCopy();
2389 if((const DataArrayInt*)_num_coords)
2390 ret->_num_coords=_num_coords->deepCopy();
2391 if((const DataArrayInt*)_rev_num_coords)
2392 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2393 if((const DataArrayAsciiChar*)_name_coords)
2394 ret->_name_coords=_name_coords->deepCopy();
2396 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2398 if((const MEDFileUMeshSplitL1 *)(*it))
2399 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2401 if((const PartDefinition*)_part_coords)
2402 ret->_part_coords=_part_coords->deepCopy();
2407 * Checks if \a this and another mesh are equal.
2408 * \param [in] other - the mesh to compare with.
2409 * \param [in] eps - a precision used to compare real values.
2410 * \param [in,out] what - the string returning description of unequal data.
2411 * \return bool - \c true if the meshes are equal, \c false, else.
2413 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2415 if(!MEDFileMesh::isEqual(other,eps,what))
2417 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2420 what="Mesh types differ ! This is unstructured and other is NOT !";
2423 clearNonDiscrAttributes();
2424 otherC->clearNonDiscrAttributes();
2425 const DataArrayDouble *coo1=_coords;
2426 const DataArrayDouble *coo2=otherC->_coords;
2427 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2429 what="Mismatch of coordinates ! One is defined and not other !";
2434 bool ret=coo1->isEqual(*coo2,eps);
2437 what="Coords differ !";
2441 const DataArrayInt *famc1=_fam_coords;
2442 const DataArrayInt *famc2=otherC->_fam_coords;
2443 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2445 what="Mismatch of families arr on nodes ! One is defined and not other !";
2450 bool ret=famc1->isEqual(*famc2);
2453 what="Families arr on node differ !";
2457 const DataArrayInt *numc1=_num_coords;
2458 const DataArrayInt *numc2=otherC->_num_coords;
2459 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2461 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2466 bool ret=numc1->isEqual(*numc2);
2469 what="Numbering arr on node differ !";
2473 const DataArrayAsciiChar *namec1=_name_coords;
2474 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2475 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2477 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2482 bool ret=namec1->isEqual(*namec2);
2485 what="Names arr on node differ !";
2489 if(_ms.size()!=otherC->_ms.size())
2491 what="Number of levels differs !";
2494 std::size_t sz=_ms.size();
2495 for(std::size_t i=0;i<sz;i++)
2497 const MEDFileUMeshSplitL1 *s1=_ms[i];
2498 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2499 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2501 what="Mismatch of presence of sub levels !";
2506 bool ret=s1->isEqual(s2,eps,what);
2511 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2514 if((!pd0 && pd1) || (pd0 && !pd1))
2516 what=std::string("node part def is defined only for one among this or other !");
2519 return pd0->isEqual(pd1,what);
2523 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2524 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2525 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2526 * \throw if internal family array is inconsistent
2527 * \sa checkSMESHConsistency()
2529 void MEDFileUMesh::checkConsistency() const
2531 if(!_coords || !_coords->isAllocated())
2534 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2536 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2537 if (!_num_coords || !_rev_num_coords)
2538 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2542 int nbCoo = _coords->getNumberOfTuples();
2544 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2547 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2549 int maxValue=_num_coords->getMaxValue(pos);
2550 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2551 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2553 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2554 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2555 if (_num_coords && !_num_coords->hasUniqueValues())
2556 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2558 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2559 // Now sub part check:
2560 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2561 it != _ms.end(); it++)
2562 (*it)->checkConsistency();
2567 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2568 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2569 * entities as it likes), or non overlapping between all sub-levels.
2570 * \throw if the condition above is not respected
2572 void MEDFileUMesh::checkSMESHConsistency() const
2575 // For all sub-levels, numbering is either always null or with void intersection:
2578 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2579 std::vector< const DataArrayInt * > v;
2580 bool voidOrNot = ((*it)->_num == 0);
2581 for (it++; it != _ms.end(); it++)
2582 if( ((*it)->_num == 0) != voidOrNot )
2583 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2584 else if (!voidOrNot)
2585 v.push_back((*it)->_num);
2588 // don't forget the 1st one:
2589 v.push_back(_ms[0]->_num);
2590 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2591 if (inter->getNumberOfTuples())
2592 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2598 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2599 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2601 void MEDFileUMesh::clearNodeAndCellNumbers()
2604 _rev_num_coords = 0;
2605 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2606 it != _ms.end(); it++)
2609 (*it)->_rev_num = 0;
2614 * Clears redundant attributes of incorporated data arrays.
2616 void MEDFileUMesh::clearNonDiscrAttributes() const
2618 MEDFileMesh::clearNonDiscrAttributes();
2619 const DataArrayDouble *coo1=_coords;
2621 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2622 const DataArrayInt *famc1=_fam_coords;
2624 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2625 const DataArrayInt *numc1=_num_coords;
2627 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2628 const DataArrayAsciiChar *namc1=_name_coords;
2630 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2631 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2633 const MEDFileUMeshSplitL1 *tmp=(*it);
2635 tmp->clearNonDiscrAttributes();
2639 void MEDFileUMesh::setName(const std::string& name)
2641 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2642 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2643 (*it)->setName(name);
2644 MEDFileMesh::setName(name);
2647 MEDFileUMesh::MEDFileUMesh()
2651 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2654 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2656 catch(INTERP_KERNEL::Exception& e)
2662 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2663 * See MEDFileUMesh::LoadPartOf for detailed description.
2667 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)
2669 MEDFileUMeshL2 loaderl2;
2670 MEDCoupling::MEDCouplingMeshType meshType;
2673 MEDCoupling::MEDCouplingAxisType dummy3;
2674 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2675 if(meshType!=UNSTRUCTURED)
2677 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2678 throw INTERP_KERNEL::Exception(oss.str().c_str());
2680 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2681 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2685 * \brief Write joints in a file
2687 void MEDFileMesh::writeJoints(med_idt fid) const
2689 if ( _joints.isNotNull() )
2690 _joints->writeLL(fid);
2694 * \brief Load joints in a file or use provided ones
2696 //================================================================================
2698 * \brief Load joints in a file or use provided ones
2699 * \param [in] fid - MED file descriptor
2700 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2701 * Usually this joints are those just read by another iteration
2702 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2704 //================================================================================
2706 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2708 if ( toUseInstedOfReading )
2709 setJoints( toUseInstedOfReading );
2711 _joints = MEDFileJoints::New( fid, _name );
2714 void MEDFileMesh::loadEquivalences(med_idt fid)
2716 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2718 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2721 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2723 const MEDFileEquivalences *equiv(other._equiv);
2725 _equiv=equiv->deepCopy(this);
2728 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2730 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2731 if(!thisEq && !otherEq)
2733 if(thisEq && otherEq)
2734 return thisEq->isEqual(otherEq,what);
2737 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2742 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2744 const MEDFileEquivalences *equiv(_equiv);
2747 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2748 _equiv->getRepr(oss);
2751 void MEDFileMesh::checkCartesian() const
2753 if(getAxisType()!=AX_CART)
2755 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()) << ").";
2756 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2757 oss << " - call setAxisType(AX_CART)" << std::endl;
2758 oss << " - call cartesianize()";
2759 throw INTERP_KERNEL::Exception(oss.str().c_str());
2764 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2766 int MEDFileMesh::getNumberOfJoints() const
2768 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2772 * \brief Return joints with all adjacent mesh domains
2774 MEDFileJoints * MEDFileMesh::getJoints() const
2776 return const_cast<MEDFileJoints*>(& (*_joints));
2779 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2781 if ( joints != _joints )
2790 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2792 * \sa loadPartUMeshFromFile
2794 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2796 MEDFileUMeshL2 loaderl2;
2797 MEDCoupling::MEDCouplingMeshType meshType;
2800 MEDCoupling::MEDCouplingAxisType axType;
2801 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2802 setAxisType(axType);
2803 if(meshType!=UNSTRUCTURED)
2805 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2806 throw INTERP_KERNEL::Exception(oss.str().c_str());
2808 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2809 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2810 // Structure element part...
2813 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
2814 nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
2818 _elt_str.resize(nModels);
2819 for(int i=0;i<nModels;i++)
2820 _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
2823 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2825 int lev=loaderl2.getNumberOfLevels();
2827 for(int i=0;i<lev;i++)
2829 if(!loaderl2.emptyLev(i))
2830 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2834 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2836 setName(loaderl2.getName());
2837 setDescription(loaderl2.getDescription());
2838 setUnivName(loaderl2.getUnivName());
2839 setIteration(loaderl2.getIteration());
2840 setOrder(loaderl2.getOrder());
2841 setTimeValue(loaderl2.getTime());
2842 setTimeUnit(loaderl2.getTimeUnit());
2843 _coords=loaderl2.getCoords();
2844 if(!mrs || mrs->isNodeFamilyFieldReading())
2845 _fam_coords=loaderl2.getCoordsFamily();
2846 if(!mrs || mrs->isNodeNumFieldReading())
2847 _num_coords=loaderl2.getCoordsNum();
2848 if(!mrs || mrs->isNodeNameFieldReading())
2849 _name_coords=loaderl2.getCoordsName();
2850 _part_coords=loaderl2.getPartDefOfCoo();
2854 MEDFileUMesh::~MEDFileUMesh()
2858 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2860 const DataArrayDouble *coo=_coords;
2861 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2862 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2863 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2864 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2865 int spaceDim=coo?coo->getNumberOfComponents():0;
2868 mdim=getMeshDimension();
2869 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2870 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2871 for(int i=0;i<spaceDim;i++)
2873 std::string info=coo->getInfoOnComponent(i);
2875 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2876 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
2877 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
2879 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2881 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2882 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2883 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2884 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2885 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2886 (*it)->write(fid,meshName,mdim);
2887 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2891 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2892 * \return std::vector<int> - a sequence of the relative dimensions.
2894 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2896 std::vector<int> ret;
2898 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2899 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2906 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2907 * \return std::vector<int> - a sequence of the relative dimensions.
2909 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2911 std::vector<int> ret0=getNonEmptyLevels();
2912 if((const DataArrayDouble *) _coords)
2914 std::vector<int> ret(ret0.size()+1);
2916 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2922 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2924 std::vector<int> ret;
2925 const DataArrayInt *famCoo(_fam_coords);
2929 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2931 const MEDFileUMeshSplitL1 *cur(*it);
2933 if(cur->getFamilyField())
2939 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2941 std::vector<int> ret;
2942 const DataArrayInt *numCoo(_num_coords);
2946 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2948 const MEDFileUMeshSplitL1 *cur(*it);
2950 if(cur->getNumberField())
2956 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2958 std::vector<int> ret;
2959 const DataArrayAsciiChar *nameCoo(_name_coords);
2963 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2965 const MEDFileUMeshSplitL1 *cur(*it);
2967 if(cur->getNameField())
2974 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2975 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2976 * \param [in] fams - the name of the family of interest.
2977 * \return std::vector<int> - a sequence of the relative dimensions.
2979 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2981 std::vector<int> ret;
2982 std::vector<int> levs(getNonEmptyLevels());
2983 std::vector<int> famIds(getFamiliesIds(fams));
2984 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2985 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2991 * Returns all relative mesh levels (including nodes) where given families are defined.
2992 * \param [in] fams - the names of the families of interest.
2993 * \return std::vector<int> - a sequence of the relative dimensions.
2995 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2997 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2998 const DataArrayInt *famCoords(_fam_coords);
3001 std::vector<int> famIds(getFamiliesIds(fams));
3002 if(famCoords->presenceOfValue(famIds))
3004 std::vector<int> ret(ret0.size()+1);
3006 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3013 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3015 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3016 if((const DataArrayInt *)_fam_coords)
3018 int val=_fam_coords->getMaxValue(tmp);
3019 ret=std::max(ret,std::abs(val));
3021 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3023 if((const MEDFileUMeshSplitL1 *)(*it))
3025 const DataArrayInt *da=(*it)->getFamilyField();
3028 int val=da->getMaxValue(tmp);
3029 ret=std::max(ret,std::abs(val));
3036 int MEDFileUMesh::getMaxFamilyIdInArrays() 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,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,val);
3059 int MEDFileUMesh::getMinFamilyIdInArrays() const
3061 int ret=std::numeric_limits<int>::max(),tmp=-1;
3062 if((const DataArrayInt *)_fam_coords)
3064 int val=_fam_coords->getMinValue(tmp);
3065 ret=std::min(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->getMinValue(tmp);
3075 ret=std::min(ret,val);
3083 * Returns the dimension on cells in \a this mesh.
3084 * \return int - the mesh dimension.
3085 * \throw If there are no cells in this mesh.
3087 int MEDFileUMesh::getMeshDimension() const
3090 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3091 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3092 return (*it)->getMeshDimension()+lev;
3093 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3097 * Returns the space dimension of \a this mesh that is equal to number of components in
3098 * the node coordinates array.
3099 * \return int - the space dimension of \a this mesh.
3100 * \throw If the node coordinates array is not available.
3102 int MEDFileUMesh::getSpaceDimension() const
3104 const DataArrayDouble *coo=_coords;
3106 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3107 return coo->getNumberOfComponents();
3111 * Returns a string describing \a this mesh.
3112 * \return std::string - the mesh information string.
3114 std::string MEDFileUMesh::simpleRepr() const
3116 std::ostringstream oss;
3117 oss << MEDFileMesh::simpleRepr();
3118 const DataArrayDouble *coo=_coords;
3119 oss << "- The dimension of the space is ";
3120 static const char MSG1[]= "*** NO COORDS SET ***";
3121 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3123 oss << _coords->getNumberOfComponents() << std::endl;
3125 oss << MSG1 << std::endl;
3126 oss << "- Type of the mesh : UNSTRUCTURED\n";
3127 oss << "- Number of nodes : ";
3129 oss << _coords->getNumberOfTuples() << std::endl;
3131 oss << MSG1 << std::endl;
3132 std::size_t nbOfLev=_ms.size();
3133 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3134 for(std::size_t i=0;i<nbOfLev;i++)
3136 const MEDFileUMeshSplitL1 *lev=_ms[i];
3137 oss << " - Level #" << -((int) i) << " has dimension : ";
3140 oss << lev->getMeshDimension() << std::endl;
3141 lev->simpleRepr(oss);
3144 oss << MSG2 << std::endl;
3146 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3149 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3150 oss << "- Names of coordinates :" << std::endl;
3151 std::vector<std::string> vars=coo->getVarsOnComponent();
3152 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3153 oss << std::endl << "- Units of coordinates : " << std::endl;
3154 std::vector<std::string> units=coo->getUnitsOnComponent();
3155 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3157 oss << std::endl << std::endl;
3159 getEquivalencesRepr(oss);
3164 * Returns a full textual description of \a this mesh.
3165 * \return std::string - the string holding the mesh description.
3167 std::string MEDFileUMesh::advancedRepr() const
3169 return simpleRepr();
3173 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3174 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3175 * \return int - the number of entities.
3176 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3178 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3180 if(meshDimRelToMaxExt==1)
3182 if(!((const DataArrayDouble *)_coords))
3183 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3184 return _coords->getNumberOfTuples();
3186 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3190 * Returns the family field for mesh entities of a given dimension.
3191 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3192 * \return const DataArrayInt * - the family field. It is an array of ids of families
3193 * each mesh entity belongs to. It can be \c NULL.
3195 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3197 if(meshDimRelToMaxExt==1)
3199 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3200 return l1->getFamilyField();
3203 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3205 if(meshDimRelToMaxExt==1)
3207 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3208 return l1->getFamilyField();
3212 * Returns the optional numbers of mesh entities of a given dimension.
3213 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3214 * \return const DataArrayInt * - the array of the entity numbers.
3215 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3217 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3219 if(meshDimRelToMaxExt==1)
3221 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3222 return l1->getNumberField();
3225 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3227 if(meshDimRelToMaxExt==1)
3228 return _name_coords;
3229 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3230 return l1->getNameField();
3234 * 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).
3236 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3237 * \param [in] gt - The input geometric type for which the part definition is requested.
3238 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3240 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3242 if(meshDimRelToMaxExt==1)
3243 return _part_coords;
3244 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3245 return l1->getPartDef(gt);
3248 int MEDFileUMesh::getNumberOfNodes() const
3250 const DataArrayDouble *coo(_coords);
3252 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3253 return coo->getNumberOfTuples();
3256 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3258 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3259 return l1->getNumberOfCells();
3262 bool MEDFileUMesh::hasImplicitPart() const
3267 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3269 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3272 void MEDFileUMesh::releaseImplicitPartIfAny() const
3276 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3278 std::size_t sz(st.getNumberOfItems());
3279 for(std::size_t i=0;i<sz;i++)
3281 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3282 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3283 if(st[i].getPflName().empty())
3284 m->computeNodeIdsAlg(nodesFetched);
3287 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3288 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3289 m2->computeNodeIdsAlg(nodesFetched);
3294 MEDFileMesh *MEDFileUMesh::cartesianize() const
3296 if(getAxisType()==AX_CART)
3299 return const_cast<MEDFileUMesh *>(this);
3303 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3304 const DataArrayDouble *coords(_coords);
3306 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3307 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3308 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3309 if((const MEDFileUMeshSplitL1 *)(*it))
3310 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3311 ret->_coords=coordsCart;
3312 ret->setAxisType(AX_CART);
3317 bool MEDFileUMesh::presenceOfStructureElements() const
3319 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
3320 if((*it).isNotNull())
3325 void MEDFileUMesh::killStructureElements()
3331 * Returns the optional numbers of mesh entities of a given dimension transformed using
3332 * DataArrayInt::invertArrayN2O2O2N().
3333 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3334 * \return const DataArrayInt * - the array of the entity numbers transformed using
3335 * DataArrayInt::invertArrayN2O2O2N().
3336 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3338 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3340 if(meshDimRelToMaxExt==1)
3342 if(!((const DataArrayInt *)_num_coords))
3343 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3344 return _rev_num_coords;
3346 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3347 return l1->getRevNumberField();
3351 * Returns a pointer to the node coordinates array of \a this mesh \b without
3352 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3354 DataArrayDouble *MEDFileUMesh::getCoords() const
3357 MCAuto<DataArrayDouble> tmp(_coords);
3358 if((DataArrayDouble *)tmp)
3366 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3367 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3369 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3370 * \param [in] grp - the name of the group whose mesh entities are included in the
3372 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3373 * according to the optional numbers of entities, if available.
3374 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3375 * delete this mesh using decrRef() as it is no more needed.
3376 * \throw If the name of a nonexistent group is specified.
3377 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3379 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3382 synchronizeTinyInfoOnLeaves();
3383 std::vector<std::string> tmp(1);
3385 return getGroups(meshDimRelToMaxExt,tmp,renum);
3389 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3390 * groups 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] grps - a sequence of group names 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 a name of a nonexistent group is present in \a grps.
3400 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3402 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3405 synchronizeTinyInfoOnLeaves();
3406 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3407 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3408 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3409 zeRet->setName(grps[0]);
3410 return zeRet.retn();
3414 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3415 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3417 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3418 * \param [in] fam - the name of the family whose mesh entities are included in the
3420 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3421 * according to the optional numbers of entities, if available.
3422 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3423 * delete this mesh using decrRef() as it is no more needed.
3424 * \throw If a name of a nonexistent family is present in \a grps.
3425 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3427 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3430 synchronizeTinyInfoOnLeaves();
3431 std::vector<std::string> tmp(1);
3433 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3437 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3438 * families 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] fams - a sequence of family names 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 fams.
3448 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3450 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3453 synchronizeTinyInfoOnLeaves();
3454 if(meshDimRelToMaxExt==1)
3456 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3457 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3458 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3462 std::vector<int> famIds=getFamiliesIds(fams);
3463 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3464 MCAuto<MEDCouplingUMesh> zeRet;
3466 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3468 zeRet=l1->getFamilyPart(0,0,renum);
3469 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3470 zeRet->setName(fams[0]);
3471 return zeRet.retn();
3475 * Returns ids of mesh entities contained in given families of a given dimension.
3476 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3478 * \param [in] fams - the names of the families of interest.
3479 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3480 * returned instead of ids.
3481 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3482 * numbers, if available and required, of mesh entities of the families. The caller
3483 * is to delete this array using decrRef() as it is no more needed.
3484 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3486 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3488 std::vector<int> famIds=getFamiliesIds(fams);
3489 if(meshDimRelToMaxExt==1)
3491 if((const DataArrayInt *)_fam_coords)
3493 MCAuto<DataArrayInt> da;
3495 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3497 da=_fam_coords->findIdsEqualList(0,0);
3499 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3504 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3506 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3508 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3510 return l1->getFamilyPartArr(0,0,renum);
3514 * Returns a MEDCouplingUMesh of a given relative dimension.
3515 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3516 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3517 * To build a valid MEDCouplingUMesh from the returned one in this case,
3518 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3519 * \param [in] meshDimRelToMax - the relative dimension of interest.
3520 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3521 * optional numbers of mesh entities.
3522 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3523 * delete using decrRef() as it is no more needed.
3524 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3526 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3529 synchronizeTinyInfoOnLeaves();
3530 if(meshDimRelToMaxExt==1)
3534 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3535 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3536 umesh->setCoords(cc);
3537 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3538 umesh->setName(getName());
3542 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3543 return l1->getWholeMesh(renum);
3546 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3548 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3549 return l1->getDistributionOfTypes();
3553 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3554 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3555 * optional numbers of mesh entities.
3556 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3557 * delete using decrRef() as it is no more needed.
3558 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3560 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3562 return getMeshAtLevel(0,renum);
3566 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3567 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3568 * optional numbers of mesh entities.
3569 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3570 * delete using decrRef() as it is no more needed.
3571 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3573 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3575 return getMeshAtLevel(-1,renum);
3579 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3580 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3581 * optional numbers of mesh entities.
3582 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3583 * delete using decrRef() as it is no more needed.
3584 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3586 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3588 return getMeshAtLevel(-2,renum);
3592 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3593 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3594 * optional numbers of mesh entities.
3595 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3596 * delete using decrRef() as it is no more needed.
3597 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3599 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3601 return getMeshAtLevel(-3,renum);
3605 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3606 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3607 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3608 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3610 void MEDFileUMesh::forceComputationOfParts() const
3612 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3614 const MEDFileUMeshSplitL1 *elt(*it);
3616 elt->forceComputationOfParts();
3621 * This method returns a vector of mesh parts containing each exactly one geometric type.
3622 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3623 * This method is only for memory aware users.
3624 * The returned pointers are **NOT** new object pointer. No need to mange them.
3626 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3629 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3630 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3634 * This method returns the part of \a this having the geometric type \a gt.
3635 * If such part is not existing an exception will be thrown.
3636 * The returned pointer is **NOT** new object pointer. No need to mange it.
3638 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3641 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3642 int lev=(int)cm.getDimension()-getMeshDimension();
3643 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3644 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3648 * This method returns for each geo types in \a this number of cells with this geo type.
3649 * 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.
3650 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3652 * \sa getDistributionOfTypes
3654 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3656 std::vector< std::pair<int,int> > ret;
3657 std::vector<int> nel(getNonEmptyLevels());
3658 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3660 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3661 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3663 int nbCells(getNumberOfCellsWithType(*it1));
3664 ret.push_back(std::pair<int,int>(*it1,nbCells));
3667 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3672 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3673 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3675 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3677 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3678 return sp->getGeoTypes();
3681 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3683 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3684 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3685 return sp->getNumberOfCellsWithType(ct);
3689 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3690 * \param [in] gt - the geometric type for which the family field is asked.
3691 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3692 * delete using decrRef() as it is no more needed.
3693 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3695 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3697 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3698 int lev=(int)cm.getDimension()-getMeshDimension();
3699 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3700 return sp->extractFamilyFieldOnGeoType(gt);
3704 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3705 * \param [in] gt - the geometric type for which the number field is asked.
3706 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3707 * delete using decrRef() as it is no more needed.
3708 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3710 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3712 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3713 int lev=(int)cm.getDimension()-getMeshDimension();
3714 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3715 return sp->extractNumberFieldOnGeoType(gt);
3719 * This method returns for specified geometric type \a gt the relative level to \a this.
3720 * If the relative level is empty an exception will be thrown.
3722 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3724 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3725 int ret((int)cm.getDimension()-getMeshDimension());
3726 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3730 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3732 if(meshDimRelToMaxExt==1)
3733 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3734 if(meshDimRelToMaxExt>1)
3735 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3736 int tracucedRk=-meshDimRelToMaxExt;
3737 if(tracucedRk>=(int)_ms.size())
3738 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3739 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3740 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3741 return _ms[tracucedRk];
3744 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3746 if(meshDimRelToMaxExt==1)
3747 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3748 if(meshDimRelToMaxExt>1)
3749 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3750 int tracucedRk=-meshDimRelToMaxExt;
3751 if(tracucedRk>=(int)_ms.size())
3752 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3753 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3754 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3755 return _ms[tracucedRk];
3758 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3760 if(-meshDimRelToMax>=(int)_ms.size())
3761 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3763 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3765 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3767 int ref=(*it)->getMeshDimension();
3768 if(ref+i!=meshDim-meshDimRelToMax)
3769 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3775 * Sets the node coordinates array of \a this mesh.
3776 * \param [in] coords - the new node coordinates array.
3777 * \throw If \a coords == \c NULL.
3779 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3782 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3783 if(coords==(DataArrayDouble *)_coords)
3785 coords->checkAllocated();
3786 int nbOfTuples(coords->getNumberOfTuples());
3789 _fam_coords=DataArrayInt::New();
3790 _fam_coords->alloc(nbOfTuples,1);
3791 _fam_coords->fillWithZero();
3792 _num_coords=0; _rev_num_coords=0; _name_coords=0;
3793 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3794 if((MEDFileUMeshSplitL1 *)(*it))
3795 (*it)->setCoords(coords);
3799 * Change coords without changing anything concerning families and numbering on nodes.
3801 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3804 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3805 if(coords==(DataArrayDouble *)_coords)
3807 coords->checkAllocated();
3808 int nbOfTuples(coords->getNumberOfTuples());
3809 if(_coords.isNull())
3816 int oldNbTuples(_coords->getNumberOfTuples());
3817 if(oldNbTuples!=nbOfTuples)
3818 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3822 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3823 if((MEDFileUMeshSplitL1 *)(*it))
3824 (*it)->setCoords(coords);
3828 * Removes all groups of a given dimension in \a this mesh.
3829 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3830 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3832 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3834 if(meshDimRelToMaxExt==1)
3836 if((DataArrayInt *)_fam_coords)
3837 _fam_coords->fillWithZero();
3840 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3841 l1->eraseFamilyField();
3846 * Removes all families with ids not present in the family fields of \a this mesh.
3848 void MEDFileUMesh::optimizeFamilies()
3850 std::vector<int> levs=getNonEmptyLevelsExt();
3851 std::set<int> allFamsIds;
3852 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3854 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3855 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3857 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3860 std::set<std::string> famNamesToKill;
3861 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3863 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3864 famNamesToKill.insert((*it).first);
3866 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3867 _families.erase(*it);
3868 std::vector<std::string> grpNamesToKill;
3869 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3871 std::vector<std::string> tmp;
3872 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3874 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3875 tmp.push_back(*it2);
3880 tmp.push_back((*it).first);
3882 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3887 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3888 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3889 * The boundary is built according to the following method:
3890 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3891 * coordinates array is extended).
3892 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3893 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3894 * might not be duplicated at all.
3895 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3896 * other side of the group is no more a neighbor)
3897 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3898 * bordering the newly created boundary use the newly computed nodes.
3899 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3900 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3902 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3903 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3905 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3906 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3907 * \sa clearNodeAndCellNumbers()
3909 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3910 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3912 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3913 typedef MCAuto<DataArrayInt> DAInt;
3915 std::vector<int> levs=getNonEmptyLevels();
3916 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3917 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3918 MUMesh m0=getMeshAtLevel(0);
3919 MUMesh m1=getMeshAtLevel(-1);
3920 int nbNodes=m0->getNumberOfNodes();
3921 MUMesh m11=getGroup(-1,grpNameM1);
3922 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3923 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3924 DAInt nodeIdsToDuplicate(tmp00);
3925 DAInt cellsToModifyConn0(tmp11);
3926 DAInt cellsToModifyConn1(tmp22);
3927 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3928 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3929 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3930 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3931 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3932 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3933 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3934 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3935 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3936 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3937 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3938 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3939 DAInt grpIds=getGroupArr(-1,grpNameM1);
3940 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3941 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3942 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3943 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3944 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3945 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3946 m0->setCoords(tmp0->getCoords());
3947 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3948 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3949 m1->setCoords(m0->getCoords());
3950 _coords=m0->getCoords(); _coords->incrRef();
3951 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3952 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3953 DataArrayInt * duplCells;
3954 m1->areCellsIncludedIn(m11, 0, duplCells);
3955 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3956 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3957 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3958 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3959 DAInt szOfCellGrpOfSameType(tmp00);
3960 DAInt idInMsOfCellGrpOfSameType(tmp11);
3962 newm1->setName(getName());
3963 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3965 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3966 DAInt newFam=DataArrayInt::New();
3967 newFam->alloc(newm1->getNumberOfCells(),1);
3968 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3969 // Positive ID for family of nodes, negative for all the rest.
3971 if (m1->getMeshDimension() == 0)
3972 idd=getMaxFamilyId()+1;
3974 idd=getMinFamilyId()-1;
3975 int globStart=0,start=0,end,globEnd;
3976 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3977 for(int i=0;i<nbOfChunks;i++)
3979 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3980 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3982 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3983 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3984 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3989 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3993 newm1->setCoords(getCoords());
3994 setMeshAtLevel(-1,newm1);
3995 setFamilyFieldArr(-1,newFam);
3996 std::string grpName2(grpNameM1); grpName2+="_dup";
3997 addFamily(grpName2,idd);
3998 addFamilyOnGrp(grpName2,grpName2);
4003 int newNbOfNodes=getCoords()->getNumberOfTuples();
4004 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
4005 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
4006 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
4011 _rev_num_coords = 0;
4012 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
4013 it != _ms.end(); it++)
4016 (*it)->_rev_num = 0;
4018 nodesDuplicated=nodeIdsToDuplicate.retn();
4019 cellsModified=cellsToModifyConn0.retn();
4020 cellsNotModified=cellsToModifyConn1.retn();
4023 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
4024 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4027 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4028 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4029 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4031 * \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.
4032 * 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.
4034 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4036 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4037 std::vector<int> levs=getNonEmptyLevels();
4039 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4040 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4043 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4045 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4046 std::vector<int> code1=m->getDistributionOfTypes();
4047 end=PutInThirdComponentOfCodeOffset(code1,start);
4048 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4049 bool hasChanged=m->unPolyze();
4050 DataArrayInt *fake=0;
4051 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4052 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4054 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4057 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4058 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4060 MCAuto<DataArrayInt> famField2,numField2;
4061 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4062 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4063 setMeshAtLevel(*it,m);
4064 std::vector<int> code2=m->getDistributionOfTypes();
4065 end=PutInThirdComponentOfCodeOffset(code2,start);
4066 newCode.insert(newCode.end(),code2.begin(),code2.end());
4068 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4072 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4073 setFamilyFieldArr(*it,newFamField);
4077 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4078 setRenumFieldArr(*it,newNumField);
4083 newCode.insert(newCode.end(),code1.begin(),code1.end());
4089 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4090 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4091 o2nRenumCell=o2nRenumCellRet.retn();
4096 /*! \cond HIDDEN_ITEMS */
4097 struct MEDLoaderAccVisit1
4099 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4100 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4101 int _new_nb_of_nodes;
4106 * 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.
4107 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4108 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4109 * -1 values in returned array means that the corresponding old node is no more used.
4111 * \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
4112 * is modified in \a this.
4113 * \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
4116 DataArrayInt *MEDFileUMesh::zipCoords()
4118 const DataArrayDouble *coo(getCoords());
4120 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4121 int nbOfNodes(coo->getNumberOfTuples());
4122 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4123 std::vector<int> neLevs(getNonEmptyLevels());
4124 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4126 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4127 if(zeLev->isMeshStoredSplitByType())
4129 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4130 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4132 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4136 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4137 mesh->computeNodeIdsAlg(nodeIdsInUse);
4140 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4141 if(nbrOfNodesInUse==nbOfNodes)
4142 return 0;//no need to update _part_coords
4143 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4144 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4145 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4146 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4147 MCAuto<DataArrayInt> newFamCoords;
4148 MCAuto<DataArrayAsciiChar> newNameCoords;
4149 if((const DataArrayInt *)_fam_coords)
4150 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4151 MCAuto<DataArrayInt> newNumCoords;
4152 if((const DataArrayInt *)_num_coords)
4153 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4154 if((const DataArrayAsciiChar *)_name_coords)
4155 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4156 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4157 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4159 if((MEDFileUMeshSplitL1*)*it)
4161 (*it)->renumberNodesInConn(ret->begin());
4162 (*it)->setCoords(_coords);
4165 // updates _part_coords
4166 const PartDefinition *pc(_part_coords);
4169 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4170 _part_coords=tmpPD->composeWith(pc);
4176 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4177 * The extraction of \a this is specified by the extractDef \a input map.
4178 * This map tells for each level of cells, the cells kept in the extraction.
4180 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4181 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4183 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4185 std::vector<int> levs(getNonEmptyLevels());
4186 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4187 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4190 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4191 if((*it).second.isNull())
4192 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4195 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4197 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4198 throw INTERP_KERNEL::Exception(oss.str());
4200 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4201 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4202 mPart->computeNodeIdsAlg(fetchedNodes);
4204 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4208 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4210 * \return - a new reference of MEDFileUMesh
4211 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4213 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4215 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4216 std::vector<int> levs(getNonEmptyLevels());
4217 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4220 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4221 if((*it).second.isNull())
4222 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4225 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4227 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4228 throw INTERP_KERNEL::Exception(oss.str());
4230 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4231 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4232 ret->setMeshAtLevel((*it).first,mPart);
4233 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4236 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4237 ret->setFamilyFieldArr((*it).first,famPart);
4241 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4242 ret->setFamilyFieldArr((*it).first,numPart);
4245 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4246 if(it2!=extractDef.end())
4248 const DataArrayDouble *coo(ret->getCoords());
4250 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4251 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4252 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4253 ret->setCoords(cooPart);
4254 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4257 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4258 ret->setFamilyFieldArr(1,famPart);
4262 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4263 ret->setFamilyFieldArr(1,numPart);
4265 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4269 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4270 m->renumberNodesInConn(o2nNodes->begin());
4271 ret->setMeshAtLevel((*it3).first,m);
4278 * This method performs an extrusion along a path defined by \a m1D.
4279 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4280 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4281 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4282 * This method scans all levels in \a this
4283 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4285 * \param [in] m1D - the mesh defining the extrusion path.
4286 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4287 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4289 * \sa MEDCouplingUMesh::buildExtrudedMesh
4291 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4294 if(getMeshDimension()!=2)
4295 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4296 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4297 m1D->checkConsistencyLight();
4298 if(m1D->getMeshDimension()!=1)
4299 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4300 int nbRep(m1D->getNumberOfCells());
4301 std::vector<int> levs(getNonEmptyLevels());
4302 std::vector<std::string> grps(getGroupsNames());
4303 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4304 DataArrayDouble *coords(0);
4305 std::size_t nbOfLevsOut(levs.size()+1);
4306 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4307 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4309 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4310 item=item->clone(false);
4311 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4312 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4313 tmp->changeSpaceDimension(3+(*lev),0.);
4314 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4315 zeList.push_back(elt);
4317 coords=elt->getCoords();
4320 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4321 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4323 (*it)->setName(getName());
4324 (*it)->setCoords(coords);
4326 for(std::size_t ii=0;ii!=zeList.size();ii++)
4329 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4332 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4333 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4334 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4335 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4336 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4337 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4338 std::vector<const MEDCouplingUMesh *> elts(3);
4339 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4340 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4341 elt->setName(getName());
4344 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4345 ret->setMeshAtLevel(lev,elt);
4347 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4348 endLev=endLev->clone(false); endLev->setCoords(coords);
4349 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4350 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4351 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4352 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4353 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4354 endLev->setName(getName());
4355 ret->setMeshAtLevel(levs.back()-1,endLev);
4357 for(std::size_t ii=0;ii!=zeList.size();ii++)
4360 std::vector< MCAuto<DataArrayInt> > outGrps;
4361 std::vector< const DataArrayInt * > outGrps2;
4364 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4366 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4367 if(!grpArr->empty())
4369 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4370 int offset0(zeList[ii]->getNumberOfCells());
4371 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4372 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4373 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4374 grpArr2->setName(oss.str());
4375 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4376 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4377 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4378 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4383 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4385 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4386 if(!grpArr->empty())
4388 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4389 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4390 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4391 for(int iii=0;iii<nbRep;iii++)
4393 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4394 grpArrs2[iii]=grpArrs[iii];
4396 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4397 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4398 std::ostringstream grpName; grpName << *grp << "_extruded";
4399 grpArrExt->setName(grpName.str());
4400 outGrps.push_back(grpArrExt);
4401 outGrps2.push_back(grpArrExt);
4404 ret->setGroupsAtLevel(lev,outGrps2);
4406 std::vector< MCAuto<DataArrayInt> > outGrps;
4407 std::vector< const DataArrayInt * > outGrps2;
4408 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4410 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4411 if(grpArr1->empty())
4413 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4414 std::ostringstream grpName; grpName << *grp << "_top";
4415 grpArr2->setName(grpName.str());
4416 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4417 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4418 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4420 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4425 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4426 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4427 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4429 * \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
4430 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4431 * \param [in] eps - detection threshold for coordinates.
4432 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4434 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4436 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4439 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4440 int initialNbNodes(getNumberOfNodes());
4441 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4442 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4444 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4446 DataArrayDouble *zeCoords(m0->getCoords());
4447 ret->setMeshAtLevel(0,m0);
4448 std::vector<int> levs(getNonEmptyLevels());
4449 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4452 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4453 ret->setFamilyFieldArr(0,famFieldCpy);
4455 famField=getFamilyFieldAtLevel(1);
4458 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4459 fam->fillWithZero();
4460 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4461 ret->setFamilyFieldArr(1,fam);
4463 ret->copyFamGrpMapsFrom(*this);
4464 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4465 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4469 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4470 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4471 if(m1->getMeshDimension()!=0)
4474 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4475 }//kill unused notUsed var
4476 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4478 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4479 MCAuto<DataArrayInt> bSafe(b);
4482 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4483 throw INTERP_KERNEL::Exception(oss.str().c_str());
4485 b->applyLin(1,initialNbNodes);
4486 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4487 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4488 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4489 m1->renumberNodesInConn(renum->begin());
4491 m1->setCoords(zeCoords);
4492 ret->setMeshAtLevel(*lev,m1);
4493 famField=getFamilyFieldAtLevel(*lev);
4496 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4497 ret->setFamilyFieldArr(*lev,famFieldCpy);
4504 * This method converts all quadratic cells in \a this into linear cells.
4505 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4506 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4508 * \param [in] eps - detection threshold for coordinates.
4509 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4511 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4513 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4516 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4517 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4518 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4519 m0->convertQuadraticCellsToLinear();
4521 DataArrayDouble *zeCoords(m0->getCoords());
4522 ret->setMeshAtLevel(0,m0);
4523 std::vector<int> levs(getNonEmptyLevels());
4524 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4527 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4528 ret->setFamilyFieldArr(0,famFieldCpy);
4530 famField=getFamilyFieldAtLevel(1);
4533 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4534 ret->setFamilyFieldArr(1,fam);
4536 ret->copyFamGrpMapsFrom(*this);
4537 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4541 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4542 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4543 m1->convertQuadraticCellsToLinear();
4546 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4547 MCAuto<DataArrayInt> bSafe(b);
4550 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4551 throw INTERP_KERNEL::Exception(oss.str().c_str());
4553 m1->renumberNodesInConn(b->begin());
4554 m1->setCoords(zeCoords);
4555 ret->setMeshAtLevel(*lev,m1);
4556 famField=getFamilyFieldAtLevel(*lev);
4559 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4560 ret->setFamilyFieldArr(*lev,famFieldCpy);
4567 * Computes the symmetry of \a this.
4568 * \return a new object.
4570 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4572 MCAuto<MEDFileUMesh> ret(deepCopy());
4573 DataArrayDouble *myCoo(getCoords());
4576 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4577 ret->setCoordsForced(newCoo);
4582 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4585 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4586 std::size_t sz(meshes.size()),i(0);
4587 std::vector<const DataArrayDouble *> coos(sz);
4588 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4589 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4592 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4593 coos[i]=(*it)->getCoords();
4594 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4595 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4597 const MEDFileUMesh *ref(meshes[0]);
4598 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4599 std::vector<int> levs(ref->getNonEmptyLevels());
4600 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4601 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4602 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4603 std::map<std::string,int> map1;
4604 std::map<std::string, std::vector<std::string> > map2;
4605 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4607 if((*it)->getSpaceDimension()!=spaceDim)
4608 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4609 if((*it)->getMeshDimension()!=meshDim)
4610 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4611 if((*it)->getNonEmptyLevels()!=levs)
4612 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4613 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4615 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4616 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4617 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4618 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4620 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4621 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4622 map1[(*it3).first]=(*it3).second;
4623 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4624 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4625 map2[(*it4).first]=(*it4).second;
4627 // Easy part : nodes
4628 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4629 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4630 ret->setCoords(coo);
4631 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4633 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4634 ret->setFamilyFieldArr(1,fam_coo);
4636 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4638 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4639 ret->setRenumFieldArr(1,num_coo);
4642 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4644 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4645 if(it2==m_mesh.end())
4646 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4647 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4648 mesh->setCoords(coo); mesh->setName(ref->getName());
4649 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4650 ret->setMeshAtLevel(*it,mesh);
4651 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4652 if(it3!=m_fam.end())
4654 const std::vector<const DataArrayInt *>& fams((*it3).second);
4655 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4657 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4658 famm->renumberInPlace(renum->begin());
4659 ret->setFamilyFieldArr(*it,famm);
4662 if(it4!=m_renum.end())
4664 const std::vector<const DataArrayInt *>& renums((*it4).second);
4665 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4667 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4668 renumm->renumberInPlace(renum->begin());
4669 ret->setRenumFieldArr(*it,renumm);
4674 ret->setFamilyInfo(map1);
4675 ret->setGroupInfo(map2);
4676 ret->setName(ref->getName());
4680 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4682 if(getMeshDimension()!=3)
4683 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4684 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4685 if(m3D.isNull() || m2D.isNull())
4686 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4687 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4688 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4692 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4694 clearNonDiscrAttributes();
4695 forceComputationOfParts();
4696 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4697 std::vector<int> layer0;
4698 layer0.push_back(getAxisType());//0 i
4699 layer0.push_back(_order); //1 i
4700 layer0.push_back(_iteration);//2 i
4701 layer0.push_back(getSpaceDimension());//3 i
4702 tinyDouble.push_back(_time);//0 d
4703 tinyStr.push_back(_name);//0 s
4704 tinyStr.push_back(_desc_name);//1 s
4705 for(int i=0;i<getSpaceDimension();i++)
4706 tinyStr.push_back(_coords->getInfoOnComponent(i));
4707 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4708 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4710 tinyStr.push_back((*it).first);
4711 layer0.push_back((*it).second);
4713 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4714 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4716 layer0.push_back((int)(*it0).second.size());
4717 tinyStr.push_back((*it0).first);
4718 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4719 tinyStr.push_back(*it1);
4721 // sizeof(layer0)==4+aa+1+bb layer#0
4722 bigArrayD=_coords;// 0 bd
4723 bigArraysI.push_back(_fam_coords);// 0 bi
4724 bigArraysI.push_back(_num_coords);// 1 bi
4725 const PartDefinition *pd(_part_coords);
4727 layer0.push_back(-1);
4730 std::vector<int> tmp0;
4731 pd->serialize(tmp0,bigArraysI);
4732 tinyInt.push_back(tmp0.size());
4733 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4736 std::vector<int> layer1;
4737 std::vector<int> levs(getNonEmptyLevels());
4738 layer1.push_back((int)levs.size());// 0 i <- key
4739 layer1.insert(layer1.end(),levs.begin(),levs.end());
4740 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4742 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4743 lev->serialize(layer1,bigArraysI);
4745 // put layers all together.
4746 tinyInt.push_back(layer0.size());
4747 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4748 tinyInt.push_back(layer1.size());
4749 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4752 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4753 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4755 int sz0(tinyInt[0]);
4756 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4757 int sz1(tinyInt[sz0+1]);
4758 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4760 std::reverse(layer0.begin(),layer0.end());
4761 std::reverse(layer1.begin(),layer1.end());
4762 std::reverse(tinyDouble.begin(),tinyDouble.end());
4763 std::reverse(tinyStr.begin(),tinyStr.end());
4764 std::reverse(bigArraysI.begin(),bigArraysI.end());
4766 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4767 _order=layer0.back(); layer0.pop_back();
4768 _iteration=layer0.back(); layer0.pop_back();
4769 int spaceDim(layer0.back()); layer0.pop_back();
4770 _time=tinyDouble.back(); tinyDouble.pop_back();
4771 _name=tinyStr.back(); tinyStr.pop_back();
4772 _desc_name=tinyStr.back(); tinyStr.pop_back();
4773 _coords=bigArrayD; _coords->rearrange(spaceDim);
4774 for(int i=0;i<spaceDim;i++)
4776 _coords->setInfoOnComponent(i,tinyStr.back());
4779 int nbOfFams(layer0.back()); layer0.pop_back();
4781 for(int i=0;i<nbOfFams;i++)
4783 _families[tinyStr.back()]=layer0.back();
4784 tinyStr.pop_back(); layer0.pop_back();
4786 int nbGroups(layer0.back()); layer0.pop_back();
4788 for(int i=0;i<nbGroups;i++)
4790 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4791 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4792 std::vector<std::string> fams(nbOfFamsOnGrp);
4793 for(int j=0;j<nbOfFamsOnGrp;j++)
4795 fams[j]=tinyStr.back(); tinyStr.pop_back();
4797 _groups[grpName]=fams;
4799 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4800 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4802 int isPd(layer0.back()); layer0.pop_back();
4805 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4806 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4807 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4810 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4812 int nbLevs(layer1.back()); layer1.pop_back();
4813 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4815 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4816 _ms.resize(maxLev+1);
4817 for(int i=0;i<nbLevs;i++)
4821 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4826 * Adds a group of nodes to \a this mesh.
4827 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4828 * The ids should be sorted and different each other (MED file norm).
4830 * \warning this method can alter default "FAMILLE_ZERO" family.
4831 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4833 * \throw If the node coordinates array is not set.
4834 * \throw If \a ids == \c NULL.
4835 * \throw If \a ids->getName() == "".
4836 * \throw If \a ids does not respect the MED file norm.
4837 * \throw If a group with name \a ids->getName() already exists.
4839 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4841 const DataArrayDouble *coords(_coords);
4843 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4844 int nbOfNodes(coords->getNumberOfTuples());
4845 if(!((DataArrayInt *)_fam_coords))
4846 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4848 addGroupUnderground(true,ids,_fam_coords);
4852 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4854 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4855 * The ids should be sorted and different each other (MED file norm).
4857 * \warning this method can alter default "FAMILLE_ZERO" family.
4858 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4860 * \throw If the node coordinates array is not set.
4861 * \throw If \a ids == \c NULL.
4862 * \throw If \a ids->getName() == "".
4863 * \throw If \a ids does not respect the MED file norm.
4864 * \throw If a group with name \a ids->getName() already exists.
4866 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4868 std::vector<int> levs(getNonEmptyLevelsExt());
4869 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4871 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4872 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4874 if(meshDimRelToMaxExt==1)
4875 { addNodeGroup(ids); return ; }
4876 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4877 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4878 addGroupUnderground(false,ids,fam);
4882 * Changes a name of a family specified by its id.
4883 * \param [in] id - the id of the family of interest.
4884 * \param [in] newFamName - the new family name.
4885 * \throw If no family with the given \a id exists.
4887 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4889 std::string oldName=getFamilyNameGivenId(id);
4890 _families.erase(oldName);
4891 _families[newFamName]=id;
4895 * Removes a mesh of a given dimension.
4896 * \param [in] meshDimRelToMax - the relative dimension of interest.
4897 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4899 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4901 std::vector<int> levSet=getNonEmptyLevels();
4902 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4903 if(it==levSet.end())
4904 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4905 int pos=(-meshDimRelToMax);
4910 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4911 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4912 * \param [in] m - the new mesh to set.
4913 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4915 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4916 * another node coordinates array.
4917 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4918 * to the existing meshes of other levels of \a this mesh.
4920 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4922 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4923 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4927 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4928 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4929 * \param [in] m - the new mesh to set.
4930 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4931 * writing \a this mesh in a MED file.
4932 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4934 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4935 * another node coordinates array.
4936 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4937 * to the existing meshes of other levels of \a this mesh.
4939 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4941 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4942 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4945 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4947 dealWithTinyInfo(m);
4948 std::vector<int> levSet=getNonEmptyLevels();
4949 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4951 if((DataArrayDouble *)_coords==0)
4953 DataArrayDouble *c=m->getCoords();
4958 if(m->getCoords()!=_coords)
4959 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4960 int sz=(-meshDimRelToMax)+1;
4961 if(sz>=(int)_ms.size())
4963 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4967 return _ms[-meshDimRelToMax];
4971 * This method allows to set at once the content of different levels in \a this.
4972 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4974 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4975 * \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.
4976 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4978 * \throw If \a there is a null pointer in \a ms.
4979 * \sa MEDFileUMesh::setMeshAtLevel
4981 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4985 const MEDCouplingUMesh *mRef=ms[0];
4987 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4988 std::string name(mRef->getName());
4989 const DataArrayDouble *coo(mRef->getCoords());
4992 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4994 const MEDCouplingUMesh *cur(*it);
4996 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4997 if(coo!=cur->getCoords())
4998 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4999 int mdim=cur->getMeshDimension();
5000 zeDim=std::max(zeDim,mdim);
5001 if(s.find(mdim)!=s.end())
5002 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
5004 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
5006 int mdim=(*it)->getMeshDimension();
5007 setName((*it)->getName());
5008 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
5014 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
5015 * meshes each representing a group, and creates corresponding groups in \a this mesh.
5016 * The given meshes must share the same node coordinates array.
5017 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
5018 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5019 * create in \a this mesh.
5020 * \throw If \a ms is empty.
5021 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5022 * to the existing meshes of other levels of \a this mesh.
5023 * \throw If the meshes in \a ms do not share the same node coordinates array.
5024 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5025 * of the given meshes.
5026 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5027 * \throw If names of some meshes in \a ms are equal.
5028 * \throw If \a ms includes a mesh with an empty name.
5030 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5033 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5034 int sz=(-meshDimRelToMax)+1;
5035 if(sz>=(int)_ms.size())
5037 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5038 DataArrayDouble *coo=checkMultiMesh(ms);
5039 if((DataArrayDouble *)_coords==0)
5045 if((DataArrayDouble *)_coords!=coo)
5046 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5047 std::vector<DataArrayInt *> corr;
5048 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5049 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5050 setMeshAtLevel(meshDimRelToMax,m,renum);
5051 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5052 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5056 * Creates groups at a given level in \a this mesh from a sequence of
5057 * meshes each representing a group.
5058 * The given meshes must share the same node coordinates array.
5059 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5060 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5061 * create in \a this mesh.
5062 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5064 * \throw If \a ms is empty.
5065 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5066 * to the existing meshes of other levels of \a this mesh.
5067 * \throw If the meshes in \a ms do not share the same node coordinates array.
5068 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5069 * of the given meshes.
5070 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5071 * \throw If names of some meshes in \a ms are equal.
5072 * \throw If \a ms includes a mesh with an empty name.
5074 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5077 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5078 int sz=(-meshDimRelToMax)+1;
5079 if(sz>=(int)_ms.size())
5081 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5082 DataArrayDouble *coo=checkMultiMesh(ms);
5083 if((DataArrayDouble *)_coords==0)
5089 if((DataArrayDouble *)_coords!=coo)
5090 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5091 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5092 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5094 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5096 DataArrayInt *arr=0;
5097 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5101 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5102 throw INTERP_KERNEL::Exception(oss.str().c_str());
5105 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5106 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5109 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5111 const DataArrayDouble *ret=ms[0]->getCoords();
5112 int mdim=ms[0]->getMeshDimension();
5113 for(unsigned int i=1;i<ms.size();i++)
5115 ms[i]->checkConsistencyLight();
5116 if(ms[i]->getCoords()!=ret)
5117 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5118 if(ms[i]->getMeshDimension()!=mdim)
5119 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5121 return const_cast<DataArrayDouble *>(ret);
5125 * Sets the family field of a given relative dimension.
5126 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5127 * the family field is set.
5128 * \param [in] famArr - the array of the family field.
5129 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5130 * \throw If \a famArr has an invalid size.
5132 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5134 if(meshDimRelToMaxExt==1)
5141 DataArrayDouble *coo(_coords);
5143 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5144 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5149 if(meshDimRelToMaxExt>1)
5150 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5151 int traducedRk=-meshDimRelToMaxExt;
5152 if(traducedRk>=(int)_ms.size())
5153 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5154 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5155 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5156 return _ms[traducedRk]->setFamilyArr(famArr);
5160 * Sets the optional numbers of mesh entities of a given dimension.
5161 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5162 * \param [in] renumArr - the array of the numbers.
5163 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5164 * \throw If \a renumArr has an invalid size.
5166 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5168 if(meshDimRelToMaxExt==1)
5176 DataArrayDouble *coo(_coords);
5178 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5179 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5180 renumArr->incrRef();
5181 _num_coords=renumArr;
5185 if(meshDimRelToMaxExt>1)
5186 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5187 int traducedRk=-meshDimRelToMaxExt;
5188 if(traducedRk>=(int)_ms.size())
5189 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5190 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5191 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5192 return _ms[traducedRk]->setRenumArr(renumArr);
5196 * Sets the optional names of mesh entities of a given dimension.
5197 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5198 * \param [in] nameArr - the array of the names.
5199 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5200 * \throw If \a nameArr has an invalid size.
5202 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5204 if(meshDimRelToMaxExt==1)
5211 DataArrayDouble *coo(_coords);
5213 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5214 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5216 _name_coords=nameArr;
5219 if(meshDimRelToMaxExt>1)
5220 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5221 int traducedRk=-meshDimRelToMaxExt;
5222 if(traducedRk>=(int)_ms.size())
5223 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5224 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5225 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5226 return _ms[traducedRk]->setNameArr(nameArr);
5229 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5231 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5232 if((const MEDFileUMeshSplitL1 *)(*it))
5233 (*it)->synchronizeTinyInfo(*this);
5237 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5239 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5241 DataArrayInt *arr=_fam_coords;
5243 arr->changeValue(oldId,newId);
5244 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5246 MEDFileUMeshSplitL1 *sp=(*it);
5249 sp->changeFamilyIdArr(oldId,newId);
5254 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5256 std::list< MCAuto<DataArrayInt> > ret;
5257 const DataArrayInt *da(_fam_coords);
5259 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5260 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5262 const MEDFileUMeshSplitL1 *elt(*it);
5265 da=elt->getFamilyField();
5267 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5273 void MEDFileUMesh::computeRevNum() const
5275 if((const DataArrayInt *)_num_coords)
5278 int maxValue=_num_coords->getMaxValue(pos);
5279 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5283 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5285 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5288 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5290 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5291 ret.push_back((const DataArrayInt *)_fam_nodes);
5292 ret.push_back((const DataArrayInt *)_num_nodes);
5293 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5294 ret.push_back((const DataArrayInt *)_fam_cells);
5295 ret.push_back((const DataArrayInt *)_num_cells);
5296 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5297 ret.push_back((const DataArrayInt *)_fam_faces);
5298 ret.push_back((const DataArrayInt *)_num_faces);
5299 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5300 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5301 ret.push_back((const DataArrayInt *)_rev_num_cells);
5302 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5306 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5308 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5309 if((const DataArrayInt *)_fam_nodes)
5311 int val=_fam_nodes->getMaxValue(tmp);
5312 ret=std::max(ret,std::abs(val));
5314 if((const DataArrayInt *)_fam_cells)
5316 int val=_fam_cells->getMaxValue(tmp);
5317 ret=std::max(ret,std::abs(val));
5319 if((const DataArrayInt *)_fam_faces)
5321 int val=_fam_faces->getMaxValue(tmp);
5322 ret=std::max(ret,std::abs(val));
5327 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5329 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5330 if((const DataArrayInt *)_fam_nodes)
5332 int val=_fam_nodes->getMaxValue(tmp);
5333 ret=std::max(ret,val);
5335 if((const DataArrayInt *)_fam_cells)
5337 int val=_fam_cells->getMaxValue(tmp);
5338 ret=std::max(ret,val);
5340 if((const DataArrayInt *)_fam_faces)
5342 int val=_fam_faces->getMaxValue(tmp);
5343 ret=std::max(ret,val);
5348 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5350 int ret=std::numeric_limits<int>::max(),tmp=-1;
5351 if((const DataArrayInt *)_fam_nodes)
5353 int val=_fam_nodes->getMinValue(tmp);
5354 ret=std::min(ret,val);
5356 if((const DataArrayInt *)_fam_cells)
5358 int val=_fam_cells->getMinValue(tmp);
5359 ret=std::min(ret,val);
5361 if((const DataArrayInt *)_fam_faces)
5363 int val=_fam_faces->getMinValue(tmp);
5364 ret=std::min(ret,val);
5369 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5371 if(!MEDFileMesh::isEqual(other,eps,what))
5373 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5376 what="Mesh types differ ! This is structured and other is NOT !";
5379 const DataArrayInt *famc1=_fam_nodes;
5380 const DataArrayInt *famc2=otherC->_fam_nodes;
5381 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5383 what="Mismatch of families arr on nodes ! One is defined and not other !";
5388 bool ret=famc1->isEqual(*famc2);
5391 what="Families arr on nodes differ !";
5396 famc2=otherC->_fam_cells;
5397 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5399 what="Mismatch of families arr on cells ! One is defined and not other !";
5404 bool ret=famc1->isEqual(*famc2);
5407 what="Families arr on cells differ !";
5412 famc2=otherC->_fam_faces;
5413 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5415 what="Mismatch of families arr on faces ! One is defined and not other !";
5420 bool ret=famc1->isEqual(*famc2);
5423 what="Families arr on faces differ !";
5428 famc2=otherC->_num_nodes;
5429 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5431 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5436 bool ret=famc1->isEqual(*famc2);
5439 what="Numbering arr on nodes differ !";
5444 famc2=otherC->_num_cells;
5445 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5447 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5452 bool ret=famc1->isEqual(*famc2);
5455 what="Numbering arr on cells differ !";
5460 famc2=otherC->_num_faces;
5461 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5463 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5468 bool ret=famc1->isEqual(*famc2);
5471 what="Numbering arr on faces differ !";
5475 const DataArrayAsciiChar *d1=_names_cells;
5476 const DataArrayAsciiChar *d2=otherC->_names_cells;
5477 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5479 what="Mismatch of naming arr on cells ! One is defined and not other !";
5484 bool ret=d1->isEqual(*d2);
5487 what="Naming arr on cells differ !";
5492 d2=otherC->_names_faces;
5493 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5495 what="Mismatch of naming arr on faces ! One is defined and not other !";
5500 bool ret=d1->isEqual(*d2);
5503 what="Naming arr on faces differ !";
5508 d2=otherC->_names_nodes;
5509 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5511 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5516 bool ret=d1->isEqual(*d2);
5519 what="Naming arr on nodes differ !";
5526 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5528 MEDFileMesh::clearNonDiscrAttributes();
5529 const DataArrayInt *tmp=_fam_nodes;
5531 (const_cast<DataArrayInt *>(tmp))->setName("");
5534 (const_cast<DataArrayInt *>(tmp))->setName("");
5537 (const_cast<DataArrayInt *>(tmp))->setName("");
5540 (const_cast<DataArrayInt *>(tmp))->setName("");
5543 (const_cast<DataArrayInt *>(tmp))->setName("");
5546 (const_cast<DataArrayInt *>(tmp))->setName("");
5550 * Returns ids of mesh entities contained in given families of a given dimension.
5551 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5553 * \param [in] fams - the names of the families of interest.
5554 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5555 * returned instead of ids.
5556 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5557 * numbers, if available and required, of mesh entities of the families. The caller
5558 * is to delete this array using decrRef() as it is no more needed.
5559 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5561 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5563 std::vector<int> famIds(getFamiliesIds(fams));
5564 switch(meshDimRelToMaxExt)
5568 if((const DataArrayInt *)_fam_nodes)
5570 MCAuto<DataArrayInt> da;
5572 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5574 da=_fam_nodes->findIdsEqualList(0,0);
5576 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5581 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5586 if((const DataArrayInt *)_fam_cells)
5588 MCAuto<DataArrayInt> da;
5590 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5592 da=_fam_cells->findIdsEqualList(0,0);
5594 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5599 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5604 if((const DataArrayInt *)_fam_faces)
5606 MCAuto<DataArrayInt> da;
5608 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5610 da=_fam_faces->findIdsEqualList(0,0);
5612 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5617 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5621 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5623 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5627 * Sets the family field of a given relative dimension.
5628 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5629 * the family field is set.
5630 * \param [in] famArr - the array of the family field.
5631 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5632 * \throw If \a famArr has an invalid size.
5633 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5635 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5637 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5639 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5640 switch(meshDimRelToMaxExt)
5644 int nbCells(mesh->getNumberOfCells());
5646 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5652 int nbNodes(mesh->getNumberOfNodes());
5654 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5660 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5662 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5667 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5674 * Sets the optional numbers of mesh entities of a given dimension.
5675 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5676 * \param [in] renumArr - the array of the numbers.
5677 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5678 * \throw If \a renumArr has an invalid size.
5679 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5681 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5683 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5685 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5686 switch(meshDimRelToMaxExt)
5690 int nbCells=mesh->getNumberOfCells();
5691 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5692 _num_cells=renumArr;
5697 int nbNodes=mesh->getNumberOfNodes();
5698 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5699 _num_nodes=renumArr;
5704 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5705 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5706 _num_faces=renumArr;
5710 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5713 renumArr->incrRef();
5717 * Sets the optional names of mesh entities of a given dimension.
5718 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5719 * \param [in] nameArr - the array of the names.
5720 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5721 * \throw If \a nameArr has an invalid size.
5723 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5725 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5727 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5728 switch(meshDimRelToMaxExt)
5732 int nbCells=mesh->getNumberOfCells();
5733 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5734 _names_cells=nameArr;
5739 int nbNodes=mesh->getNumberOfNodes();
5740 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5741 _names_nodes=nameArr;
5746 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5747 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5748 _names_cells=nameArr;
5751 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5758 * Adds a group of nodes to \a this mesh.
5759 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5760 * The ids should be sorted and different each other (MED file norm).
5762 * \warning this method can alter default "FAMILLE_ZERO" family.
5763 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5765 * \throw If the node coordinates array is not set.
5766 * \throw If \a ids == \c NULL.
5767 * \throw If \a ids->getName() == "".
5768 * \throw If \a ids does not respect the MED file norm.
5769 * \throw If a group with name \a ids->getName() already exists.
5771 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5777 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5779 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5780 * The ids should be sorted and different each other (MED file norm).
5782 * \warning this method can alter default "FAMILLE_ZERO" family.
5783 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5785 * \throw If the node coordinates array is not set.
5786 * \throw If \a ids == \c NULL.
5787 * \throw If \a ids->getName() == "".
5788 * \throw If \a ids does not respect the MED file norm.
5789 * \throw If a group with name \a ids->getName() already exists.
5791 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5793 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5794 addGroupUnderground(false,ids,fam);
5799 * Returns the family field for mesh entities of a given dimension.
5800 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5801 * \return const DataArrayInt * - the family field. It is an array of ids of families
5802 * each mesh entity belongs to. It can be \c NULL.
5803 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5805 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5807 switch(meshDimRelToMaxExt)
5816 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5821 * Returns the family field for mesh entities of a given dimension.
5822 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5823 * \return const DataArrayInt * - the family field. It is an array of ids of families
5824 * each mesh entity belongs to. It can be \c NULL.
5825 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5827 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5829 switch(meshDimRelToMaxExt)
5838 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5843 * Returns the optional numbers of mesh entities of a given dimension.
5844 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5845 * \return const DataArrayInt * - the array of the entity numbers.
5846 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5847 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5849 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5851 switch(meshDimRelToMaxExt)
5860 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5865 * Returns the optional numbers of mesh entities of a given dimension transformed using
5866 * DataArrayInt::invertArrayN2O2O2N().
5867 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5868 * \return const DataArrayInt * - the array of the entity numbers transformed using
5869 * DataArrayInt::invertArrayN2O2O2N().
5870 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5871 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5873 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5875 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5876 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5877 if(meshDimRelToMaxExt==0)
5879 if((const DataArrayInt *)_num_cells)
5882 int maxValue=_num_cells->getMaxValue(pos);
5883 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5884 return _rev_num_cells;
5887 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5891 if((const DataArrayInt *)_num_nodes)
5894 int maxValue=_num_nodes->getMaxValue(pos);
5895 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5896 return _rev_num_nodes;
5899 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5903 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5905 switch(meshDimRelToMaxExt)
5908 return _names_cells;
5910 return _names_nodes;
5912 return _names_faces;
5914 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5919 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5920 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5922 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5924 std::vector<int> ret(1);
5929 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5930 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5932 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5934 std::vector<int> ret(2);
5940 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5942 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5944 std::vector<int> ret;
5945 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5956 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5958 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5960 std::vector<int> ret;
5961 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5972 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5974 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5976 std::vector<int> ret;
5977 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5988 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5990 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5992 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5996 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5998 DataArrayInt *arr=_fam_nodes;
6000 arr->changeValue(oldId,newId);
6003 arr->changeValue(oldId,newId);
6006 arr->changeValue(oldId,newId);
6009 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
6011 std::list< MCAuto<DataArrayInt> > ret;
6012 const DataArrayInt *da(_fam_nodes);
6014 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6017 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6020 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
6024 void MEDFileStructuredMesh::deepCpyAttributes()
6026 if((const DataArrayInt*)_fam_nodes)
6027 _fam_nodes=_fam_nodes->deepCopy();
6028 if((const DataArrayInt*)_num_nodes)
6029 _num_nodes=_num_nodes->deepCopy();
6030 if((const DataArrayAsciiChar*)_names_nodes)
6031 _names_nodes=_names_nodes->deepCopy();
6032 if((const DataArrayInt*)_fam_cells)
6033 _fam_cells=_fam_cells->deepCopy();
6034 if((const DataArrayInt*)_num_cells)
6035 _num_cells=_num_cells->deepCopy();
6036 if((const DataArrayAsciiChar*)_names_cells)
6037 _names_cells=_names_cells->deepCopy();
6038 if((const DataArrayInt*)_fam_faces)
6039 _fam_faces=_fam_faces->deepCopy();
6040 if((const DataArrayInt*)_num_faces)
6041 _num_faces=_num_faces->deepCopy();
6042 if((const DataArrayAsciiChar*)_names_faces)
6043 _names_faces=_names_faces->deepCopy();
6044 if((const DataArrayInt*)_rev_num_nodes)
6045 _rev_num_nodes=_rev_num_nodes->deepCopy();
6046 if((const DataArrayInt*)_rev_num_cells)
6047 _rev_num_cells=_rev_num_cells->deepCopy();
6051 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
6053 * \return a pointer to cartesian mesh that need to be managed by the caller.
6054 * \warning the returned pointer has to be managed by the caller.
6058 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6059 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6060 * \param [in] renum - it must be \c false.
6061 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6062 * delete using decrRef() as it is no more needed.
6064 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6068 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6069 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6070 switch(meshDimRelToMax)
6076 return const_cast<MEDCouplingStructuredMesh *>(m);
6081 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6082 buildMinusOneImplicitPartIfNeeded();
6083 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6089 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6093 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6095 std::vector<int> ret;
6096 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6097 if(famCells && famCells->presenceOfValue(ret))
6099 if(famFaces && famFaces->presenceOfValue(ret))
6104 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6106 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6107 const DataArrayInt *famNodes(_fam_nodes);
6108 if(famNodes && famNodes->presenceOfValue(ret))
6114 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6115 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6116 * \return int - the number of entities.
6117 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6119 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6121 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6123 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6124 switch(meshDimRelToMaxExt)
6127 return cmesh->getNumberOfCells();
6129 return cmesh->getNumberOfNodes();
6131 return cmesh->getNumberOfCellsOfSubLevelMesh();
6133 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6137 int MEDFileStructuredMesh::getNumberOfNodes() const
6139 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6141 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6142 return cmesh->getNumberOfNodes();
6145 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6147 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6149 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6150 switch(meshDimRelToMaxExt)
6153 return cmesh->getNumberOfCells();
6155 return cmesh->getNumberOfCellsOfSubLevelMesh();
6157 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6161 bool MEDFileStructuredMesh::hasImplicitPart() const
6167 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6169 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6171 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6172 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6175 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6176 if(cm.getReverseExtrudedType()!=gt)
6177 throw INTERP_KERNEL::Exception(MSG);
6178 buildImplicitPart();
6179 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6183 if(gt!=zeFaceMesh->getCellModelEnum())
6184 throw INTERP_KERNEL::Exception(MSG);
6185 return zeFaceMesh->getNumberOfCells();
6189 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6191 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6193 buildImplicitPart();
6196 void MEDFileStructuredMesh::buildImplicitPart() const
6198 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6200 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6201 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6204 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6206 _faces_if_necessary=0;
6210 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6211 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6213 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6215 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6218 return _faces_if_necessary;
6221 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6223 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6225 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6226 switch(meshDimRelToMax)
6230 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6235 int mdim(cmesh->getMeshDimension());
6237 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6238 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6242 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6246 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6248 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6251 return getNumberOfCellsAtLevel(0);
6254 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6256 if(st.getNumberOfItems()!=1)
6257 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 !");
6258 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6259 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6260 if(getNumberOfNodes()!=(int)nodesFetched.size())
6261 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6262 if(st[0].getPflName().empty())
6264 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6267 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6268 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6269 int sz(nodesFetched.size());
6270 for(const int *work=arr->begin();work!=arr->end();work++)
6272 std::vector<int> conn;
6273 cmesh->getNodeIdsOfCell(*work,conn);
6274 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6275 if(*it>=0 && *it<sz)
6276 nodesFetched[*it]=true;
6278 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6282 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6284 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6288 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6289 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6291 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6292 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6294 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6297 if(!mrs || mrs->isCellFamilyFieldReading())
6299 famCells=DataArrayInt::New();
6300 famCells->alloc(nbOfElt,1);
6301 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6304 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6307 if(!mrs || mrs->isCellNumFieldReading())
6309 numCells=DataArrayInt::New();
6310 numCells->alloc(nbOfElt,1);
6311 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6314 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6317 if(!mrs || mrs->isCellNameFieldReading())
6319 namesCells=DataArrayAsciiChar::New();
6320 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6321 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6322 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6327 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6329 setName(strm->getName());
6330 setDescription(strm->getDescription());
6331 setUnivName(strm->getUnivName());
6332 setIteration(strm->getIteration());
6333 setOrder(strm->getOrder());
6334 setTimeValue(strm->getTime());
6335 setTimeUnit(strm->getTimeUnit());
6336 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6337 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6338 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6341 if(!mrs || mrs->isNodeFamilyFieldReading())
6343 int nbNodes(getNumberOfNodes());
6345 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6346 _fam_nodes=DataArrayInt::New();
6347 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6348 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...
6349 _fam_nodes->fillWithZero();
6350 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6353 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6356 if(!mrs || mrs->isNodeNumFieldReading())
6358 _num_nodes=DataArrayInt::New();
6359 _num_nodes->alloc(nbOfElt,1);
6360 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6363 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6366 if(!mrs || mrs->isNodeNameFieldReading())
6368 _names_nodes=DataArrayAsciiChar::New();
6369 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6370 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6371 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6374 int meshDim(getStructuredMesh()->getMeshDimension());
6375 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6377 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6380 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6382 int meshDim(getStructuredMesh()->getMeshDimension());
6383 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6385 if((const DataArrayInt *)_fam_cells)
6386 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6387 if((const DataArrayInt *)_fam_faces)
6388 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6389 if((const DataArrayInt *)_fam_nodes)
6390 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6391 if((const DataArrayInt *)_num_cells)
6392 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6393 if((const DataArrayInt *)_num_faces)
6394 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6395 if((const DataArrayInt *)_num_nodes)
6396 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6397 if((const DataArrayAsciiChar *)_names_cells)
6399 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6401 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6402 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6403 throw INTERP_KERNEL::Exception(oss.str().c_str());
6405 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6407 if((const DataArrayAsciiChar *)_names_faces)
6409 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6411 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6412 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6413 throw INTERP_KERNEL::Exception(oss.str().c_str());
6415 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6417 if((const DataArrayAsciiChar *)_names_nodes)
6419 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6421 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6422 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6423 throw INTERP_KERNEL::Exception(oss.str().c_str());
6425 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6428 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6432 * Returns an empty instance of MEDFileCMesh.
6433 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6434 * mesh using decrRef() as it is no more needed.
6436 MEDFileCMesh *MEDFileCMesh::New()
6438 return new MEDFileCMesh;
6442 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6443 * file. The first mesh in the file is loaded.
6444 * \param [in] fileName - the name of MED file to read.
6445 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6446 * mesh using decrRef() as it is no more needed.
6447 * \throw If the file is not readable.
6448 * \throw If there is no meshes in the file.
6449 * \throw If the mesh in the file is not a Cartesian one.
6451 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6453 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6454 return New(fid,mrs);
6457 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6459 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6463 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6464 * file. The mesh to load is specified by its name and numbers of a time step and an
6466 * \param [in] fileName - the name of MED file to read.
6467 * \param [in] mName - the name of the mesh to read.
6468 * \param [in] dt - the number of a time step.
6469 * \param [in] it - the number of an iteration.
6470 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6471 * mesh using decrRef() as it is no more needed.
6472 * \throw If the file is not readable.
6473 * \throw If there is no mesh with given attributes in the file.
6474 * \throw If the mesh in the file is not a Cartesian one.
6476 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6478 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6479 return New(fid,mName,dt,it,mrs);
6482 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6484 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6487 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6489 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6492 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6494 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6495 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6500 * Returns the dimension on cells in \a this mesh.
6501 * \return int - the mesh dimension.
6502 * \throw If there are no cells in this mesh.
6504 int MEDFileCMesh::getMeshDimension() const
6506 if(!((const MEDCouplingCMesh*)_cmesh))
6507 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6508 return _cmesh->getMeshDimension();
6512 * Returns the dimension on nodes in \a this mesh.
6513 * \return int - the space dimension.
6514 * \throw If there are no cells in this mesh.
6516 int MEDFileCMesh::getSpaceDimension() const
6518 if(!((const MEDCouplingCMesh*)_cmesh))
6519 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6520 return _cmesh->getSpaceDimension();
6524 * Returns a string describing \a this mesh.
6525 * \return std::string - the mesh information string.
6527 std::string MEDFileCMesh::simpleRepr() const
6529 return MEDFileStructuredMesh::simpleRepr();
6533 * Returns a full textual description of \a this mesh.
6534 * \return std::string - the string holding the mesh description.
6536 std::string MEDFileCMesh::advancedRepr() const
6538 return simpleRepr();
6541 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6543 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6547 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6549 return new MEDFileCMesh;
6552 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6554 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6555 ret->deepCpyEquivalences(*this);
6556 if((const MEDCouplingCMesh*)_cmesh)
6557 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6558 ret->deepCpyAttributes();
6563 * Checks if \a this and another mesh are equal.
6564 * \param [in] other - the mesh to compare with.
6565 * \param [in] eps - a precision used to compare real values.
6566 * \param [in,out] what - the string returning description of unequal data.
6567 * \return bool - \c true if the meshes are equal, \c false, else.
6569 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6571 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6573 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6576 what="Mesh types differ ! This is cartesian and other is NOT !";
6579 clearNonDiscrAttributes();
6580 otherC->clearNonDiscrAttributes();
6581 const MEDCouplingCMesh *coo1=_cmesh;
6582 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6583 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6585 what="Mismatch of cartesian meshes ! One is defined and not other !";
6590 bool ret=coo1->isEqual(coo2,eps);
6593 what="cartesian meshes differ !";
6601 * Clears redundant attributes of incorporated data arrays.
6603 void MEDFileCMesh::clearNonDiscrAttributes() const
6605 MEDFileStructuredMesh::clearNonDiscrAttributes();
6606 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6609 MEDFileCMesh::MEDFileCMesh()
6613 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6616 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6618 catch(INTERP_KERNEL::Exception& e)
6623 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6625 MEDCoupling::MEDCouplingMeshType meshType;
6628 MEDCoupling::MEDCouplingAxisType axType;
6629 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6630 if(meshType!=CARTESIAN)
6632 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6633 throw INTERP_KERNEL::Exception(oss.str().c_str());
6635 MEDFileCMeshL2 loaderl2;
6636 loaderl2.loadAll(fid,mid,mName,dt,it);
6637 setAxisType(axType);
6638 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6641 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6645 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6646 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6648 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6650 synchronizeTinyInfoOnLeaves();
6654 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6656 synchronizeTinyInfoOnLeaves();
6661 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6662 * \param [in] m - the new MEDCouplingCMesh to refer to.
6663 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6666 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6668 dealWithTinyInfo(m);
6674 MEDFileMesh *MEDFileCMesh::cartesianize() const
6676 if(getAxisType()==AX_CART)
6679 return const_cast<MEDFileCMesh *>(this);
6683 const MEDCouplingCMesh *cmesh(getMesh());
6685 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6686 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6687 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6688 clmesh->setCoords(coords);
6689 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6690 ret->MEDFileStructuredMesh::operator=(*this);
6691 ret->setMesh(clmesh);
6692 ret->setAxisType(AX_CART);
6697 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6699 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6700 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6701 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6702 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6703 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6704 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6705 int spaceDim(_cmesh->getSpaceDimension());
6706 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6707 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6708 for(int i=0;i<spaceDim;i++)
6710 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6712 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6713 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
6714 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
6716 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6718 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6719 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6720 for(int i=0;i<spaceDim;i++)
6722 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6723 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6726 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6727 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6730 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6732 const MEDCouplingCMesh *cmesh=_cmesh;
6735 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6736 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6737 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6738 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6741 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6743 return new MEDFileCurveLinearMesh;
6746 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6748 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6751 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6753 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6754 return New(fid,mrs);
6757 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6759 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6760 return New(fid,mName,dt,it,mrs);
6763 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6765 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6768 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6770 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6773 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6775 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6776 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6780 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6782 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6786 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6788 return new MEDFileCurveLinearMesh;
6791 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6793 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6794 ret->deepCpyEquivalences(*this);
6795 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6796 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6797 ret->deepCpyAttributes();
6801 int MEDFileCurveLinearMesh::getMeshDimension() const
6803 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6804 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6805 return _clmesh->getMeshDimension();
6808 std::string MEDFileCurveLinearMesh::simpleRepr() const
6810 return MEDFileStructuredMesh::simpleRepr();
6813 std::string MEDFileCurveLinearMesh::advancedRepr() const
6815 return simpleRepr();
6818 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6820 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6822 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6825 what="Mesh types differ ! This is curve linear and other is NOT !";
6828 clearNonDiscrAttributes();
6829 otherC->clearNonDiscrAttributes();
6830 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6831 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6832 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6834 what="Mismatch of curve linear meshes ! One is defined and not other !";
6839 bool ret=coo1->isEqual(coo2,eps);
6842 what="curve linear meshes differ !";
6849 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6851 MEDFileStructuredMesh::clearNonDiscrAttributes();
6852 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6855 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6857 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6860 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6861 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6862 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6863 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6866 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6868 synchronizeTinyInfoOnLeaves();
6872 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6874 dealWithTinyInfo(m);
6880 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6882 if(getAxisType()==AX_CART)
6885 return const_cast<MEDFileCurveLinearMesh *>(this);
6889 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6891 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6892 const DataArrayDouble *coords(mesh->getCoords());
6894 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6895 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6896 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6897 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6898 mesh2->setCoords(coordsCart);
6899 ret->setMesh(mesh2);
6900 ret->setAxisType(AX_CART);
6905 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6907 synchronizeTinyInfoOnLeaves();
6911 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6915 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6918 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6920 catch(INTERP_KERNEL::Exception& e)
6925 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
6927 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6928 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6929 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6930 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6931 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6932 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6933 int spaceDim=_clmesh->getSpaceDimension();
6934 int meshDim=_clmesh->getMeshDimension();
6935 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6936 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6937 const DataArrayDouble *coords=_clmesh->getCoords();
6939 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
6940 for(int i=0;i<spaceDim;i++)
6942 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6944 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6945 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
6946 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
6948 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6950 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6951 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6952 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6953 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6955 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6957 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6958 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6961 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6963 MEDCoupling::MEDCouplingMeshType meshType;
6966 MEDCoupling::MEDCouplingAxisType axType;
6967 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6968 setAxisType(axType);
6969 if(meshType!=CURVE_LINEAR)
6971 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6972 throw INTERP_KERNEL::Exception(oss.str().c_str());
6974 MEDFileCLMeshL2 loaderl2;
6975 loaderl2.loadAll(fid,mid,mName,dt,it);
6976 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6979 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6982 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6984 return new MEDFileMeshMultiTS;
6987 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
6989 return new MEDFileMeshMultiTS(fid);
6992 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6994 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6998 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
7000 return new MEDFileMeshMultiTS(fid,mName);
7003 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
7005 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7006 return New(fid,mName);
7009 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
7011 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
7012 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
7014 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
7015 if((const MEDFileMesh *)*it)
7016 meshOneTs[i]=(*it)->deepCopy();
7017 ret->_mesh_one_ts=meshOneTs;
7021 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
7023 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7026 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7028 std::vector<const BigMemoryObject *> ret;
7029 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7030 ret.push_back((const MEDFileMesh *)*it);
7034 std::string MEDFileMeshMultiTS::getName() const
7036 if(_mesh_one_ts.empty())
7037 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7038 return _mesh_one_ts[0]->getName();
7041 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7043 std::string oldName(getName());
7044 std::vector< std::pair<std::string,std::string> > v(1);
7045 v[0].first=oldName; v[0].second=newMeshName;
7049 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7052 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7054 MEDFileMesh *cur(*it);
7056 ret=cur->changeNames(modifTab) || ret;
7061 void MEDFileMeshMultiTS::cartesianizeMe()
7063 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7065 MEDFileMesh *cur(*it);
7068 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7074 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7076 if(_mesh_one_ts.empty())
7077 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7078 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7081 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7084 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7085 _mesh_one_ts.resize(1);
7086 mesh1TimeStep->incrRef();
7087 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7088 _mesh_one_ts[0]=mesh1TimeStep;
7091 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7093 if ( MEDFileMesh* m = getOneTimeStep() )
7094 return m->getJoints();
7099 * \brief Set Joints that are common to all time-stamps
7101 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7103 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7105 (*it)->setJoints( joints );
7109 bool MEDFileMeshMultiTS::presenceOfStructureElements() const
7111 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7112 if((*it).isNotNull())
7113 if((*it)->presenceOfStructureElements())
7118 void MEDFileMeshMultiTS::killStructureElements()
7120 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7121 if((*it).isNotNull())
7122 (*it)->killStructureElements();
7125 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7127 MEDFileJoints *joints(getJoints());
7128 bool jointsWritten(false);
7130 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7132 if ( jointsWritten )
7133 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7135 jointsWritten = true;
7137 (*it)->copyOptionsFrom(*this);
7138 (*it)->writeLL(fid);
7141 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7144 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7146 MEDFileJoints *joints(0);
7147 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7149 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7150 joints = getOneTimeStep()->getJoints();
7152 _mesh_one_ts.clear(); //for the moment to be improved
7153 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7156 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7160 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7163 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7166 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7167 throw INTERP_KERNEL::Exception(oss.str().c_str());
7170 MEDCoupling::MEDCouplingMeshType meshType;
7172 MEDCoupling::MEDCouplingAxisType dummy3;
7173 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7174 loadFromFile(fid,ms.front());
7176 catch(INTERP_KERNEL::Exception& e)
7181 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7184 loadFromFile(fid,mName);
7186 catch(INTERP_KERNEL::Exception& e)
7191 MEDFileMeshes *MEDFileMeshes::New()
7193 return new MEDFileMeshes;
7196 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7198 return new MEDFileMeshes(fid);
7201 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7203 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7207 void MEDFileMeshes::writeLL(med_idt fid) const
7209 checkConsistencyLight();
7210 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7212 (*it)->copyOptionsFrom(*this);
7213 (*it)->writeLL(fid);
7217 // MEDFileMeshes::writ checkConsistencyLight();
7219 int MEDFileMeshes::getNumberOfMeshes() const
7221 return _meshes.size();
7224 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7226 return new MEDFileMeshesIterator(this);
7229 /** Return a borrowed reference (caller is not responsible) */
7230 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7232 if(i<0 || i>=(int)_meshes.size())
7234 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7235 throw INTERP_KERNEL::Exception(oss.str().c_str());
7237 return _meshes[i]->getOneTimeStep();
7240 /** Return a borrowed reference (caller is not responsible) */
7241 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7243 std::vector<std::string> ms=getMeshesNames();
7244 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7247 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7248 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7249 throw INTERP_KERNEL::Exception(oss.str().c_str());
7251 return getMeshAtPos((int)std::distance(ms.begin(),it));
7254 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7256 std::vector<std::string> ret(_meshes.size());
7258 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7260 const MEDFileMeshMultiTS *f=(*it);
7263 ret[i]=f->getName();
7267 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7268 throw INTERP_KERNEL::Exception(oss.str().c_str());
7274 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7277 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7279 MEDFileMeshMultiTS *cur(*it);
7281 ret=cur->changeNames(modifTab) || ret;
7286 void MEDFileMeshes::cartesianizeMe()
7288 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7290 MEDFileMeshMultiTS *cur(*it);
7292 cur->cartesianizeMe();
7296 void MEDFileMeshes::resize(int newSize)
7298 _meshes.resize(newSize);
7301 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7304 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7305 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7306 elt->setOneTimeStep(mesh);
7307 _meshes.push_back(elt);
7310 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7313 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7314 if(i>=(int)_meshes.size())
7315 _meshes.resize(i+1);
7316 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7317 elt->setOneTimeStep(mesh);
7321 void MEDFileMeshes::destroyMeshAtPos(int i)
7323 if(i<0 || i>=(int)_meshes.size())
7325 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7326 throw INTERP_KERNEL::Exception(oss.str().c_str());
7328 _meshes.erase(_meshes.begin()+i);
7331 void MEDFileMeshes::loadFromFile(med_idt fid)
7333 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7335 _meshes.resize(ms.size());
7336 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7337 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7340 MEDFileMeshes::MEDFileMeshes()
7344 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7349 catch(INTERP_KERNEL::Exception& /*e*/)
7353 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7355 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7357 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7358 if((const MEDFileMeshMultiTS *)*it)
7359 meshes[i]=(*it)->deepCopy();
7360 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7361 ret->_meshes=meshes;
7365 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7367 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7370 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7372 std::vector<const BigMemoryObject *> ret;
7373 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7374 ret.push_back((const MEDFileMeshMultiTS *)*it);
7378 std::string MEDFileMeshes::simpleRepr() const
7380 std::ostringstream oss;
7381 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7382 simpleReprWithoutHeader(oss);
7386 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7388 int nbOfMeshes=getNumberOfMeshes();
7389 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7390 std::vector<std::string> mns=getMeshesNames();
7391 for(int i=0;i<nbOfMeshes;i++)
7392 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7395 void MEDFileMeshes::checkConsistencyLight() const
7397 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7399 std::set<std::string> s;
7400 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7402 const MEDFileMeshMultiTS *elt=(*it);
7405 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7406 throw INTERP_KERNEL::Exception(oss.str().c_str());
7408 std::size_t sz=s.size();
7409 s.insert(std::string((*it)->getName()));
7412 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7413 throw INTERP_KERNEL::Exception(oss.str().c_str());
7418 bool MEDFileMeshes::presenceOfStructureElements() const
7420 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7421 if((*it).isNotNull())
7422 if((*it)->presenceOfStructureElements())
7427 void MEDFileMeshes::killStructureElements()
7429 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7430 if((*it).isNotNull())
7431 (*it)->killStructureElements();
7434 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7439 _nb_iter=ms->getNumberOfMeshes();
7443 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7447 MEDFileMesh *MEDFileMeshesIterator::nextt()
7449 if(_iter_id<_nb_iter)
7451 MEDFileMeshes *ms(_ms);
7453 return ms->getMeshAtPos(_iter_id++);
7461 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7463 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7464 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7466 if(geoType==MED_NO_GEOTYPE)
7467 return INTERP_KERNEL::NORM_ERROR;
7468 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7469 throw INTERP_KERNEL::Exception(oss.str());
7471 return typmai2[std::distance(typmai,pos)];
7474 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7484 std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7485 throw INTERP_KERNEL::Exception(oss.str());