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>));
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);
2368 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2370 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2374 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2376 return new MEDFileUMesh;
2379 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2381 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2382 ret->deepCpyEquivalences(*this);
2383 if((const DataArrayDouble*)_coords)
2384 ret->_coords=_coords->deepCopy();
2385 if((const DataArrayInt*)_fam_coords)
2386 ret->_fam_coords=_fam_coords->deepCopy();
2387 if((const DataArrayInt*)_num_coords)
2388 ret->_num_coords=_num_coords->deepCopy();
2389 if((const DataArrayInt*)_rev_num_coords)
2390 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2391 if((const DataArrayAsciiChar*)_name_coords)
2392 ret->_name_coords=_name_coords->deepCopy();
2394 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2396 if((const MEDFileUMeshSplitL1 *)(*it))
2397 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2399 if((const PartDefinition*)_part_coords)
2400 ret->_part_coords=_part_coords->deepCopy();
2405 * Checks if \a this and another mesh are equal.
2406 * \param [in] other - the mesh to compare with.
2407 * \param [in] eps - a precision used to compare real values.
2408 * \param [in,out] what - the string returning description of unequal data.
2409 * \return bool - \c true if the meshes are equal, \c false, else.
2411 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2413 if(!MEDFileMesh::isEqual(other,eps,what))
2415 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2418 what="Mesh types differ ! This is unstructured and other is NOT !";
2421 clearNonDiscrAttributes();
2422 otherC->clearNonDiscrAttributes();
2423 const DataArrayDouble *coo1=_coords;
2424 const DataArrayDouble *coo2=otherC->_coords;
2425 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2427 what="Mismatch of coordinates ! One is defined and not other !";
2432 bool ret=coo1->isEqual(*coo2,eps);
2435 what="Coords differ !";
2439 const DataArrayInt *famc1=_fam_coords;
2440 const DataArrayInt *famc2=otherC->_fam_coords;
2441 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2443 what="Mismatch of families arr on nodes ! One is defined and not other !";
2448 bool ret=famc1->isEqual(*famc2);
2451 what="Families arr on node differ !";
2455 const DataArrayInt *numc1=_num_coords;
2456 const DataArrayInt *numc2=otherC->_num_coords;
2457 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2459 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2464 bool ret=numc1->isEqual(*numc2);
2467 what="Numbering arr on node differ !";
2471 const DataArrayAsciiChar *namec1=_name_coords;
2472 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2473 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2475 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2480 bool ret=namec1->isEqual(*namec2);
2483 what="Names arr on node differ !";
2487 if(_ms.size()!=otherC->_ms.size())
2489 what="Number of levels differs !";
2492 std::size_t sz=_ms.size();
2493 for(std::size_t i=0;i<sz;i++)
2495 const MEDFileUMeshSplitL1 *s1=_ms[i];
2496 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2497 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2499 what="Mismatch of presence of sub levels !";
2504 bool ret=s1->isEqual(s2,eps,what);
2509 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2512 if((!pd0 && pd1) || (pd0 && !pd1))
2514 what=std::string("node part def is defined only for one among this or other !");
2517 return pd0->isEqual(pd1,what);
2521 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2522 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2523 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2524 * \throw if internal family array is inconsistent
2525 * \sa checkSMESHConsistency()
2527 void MEDFileUMesh::checkConsistency() const
2529 if(!_coords || !_coords->isAllocated())
2532 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2534 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2535 if (!_num_coords || !_rev_num_coords)
2536 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2540 int nbCoo = _coords->getNumberOfTuples();
2542 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2545 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2547 int maxValue=_num_coords->getMaxValue(pos);
2548 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2549 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2551 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2552 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2553 if (_num_coords && !_num_coords->hasUniqueValues())
2554 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2556 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2557 // Now sub part check:
2558 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2559 it != _ms.end(); it++)
2560 (*it)->checkConsistency();
2565 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2566 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2567 * entities as it likes), or non overlapping between all sub-levels.
2568 * \throw if the condition above is not respected
2570 void MEDFileUMesh::checkSMESHConsistency() const
2573 // For all sub-levels, numbering is either always null or with void intersection:
2576 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2577 std::vector< const DataArrayInt * > v;
2578 bool voidOrNot = ((*it)->_num == 0);
2579 for (it++; it != _ms.end(); it++)
2580 if( ((*it)->_num == 0) != voidOrNot )
2581 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2582 else if (!voidOrNot)
2583 v.push_back((*it)->_num);
2586 // don't forget the 1st one:
2587 v.push_back(_ms[0]->_num);
2588 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2589 if (inter->getNumberOfTuples())
2590 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2596 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2597 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2599 void MEDFileUMesh::clearNodeAndCellNumbers()
2602 _rev_num_coords = 0;
2603 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2604 it != _ms.end(); it++)
2607 (*it)->_rev_num = 0;
2612 * Clears redundant attributes of incorporated data arrays.
2614 void MEDFileUMesh::clearNonDiscrAttributes() const
2616 MEDFileMesh::clearNonDiscrAttributes();
2617 const DataArrayDouble *coo1=_coords;
2619 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2620 const DataArrayInt *famc1=_fam_coords;
2622 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2623 const DataArrayInt *numc1=_num_coords;
2625 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2626 const DataArrayAsciiChar *namc1=_name_coords;
2628 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2629 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2631 const MEDFileUMeshSplitL1 *tmp=(*it);
2633 tmp->clearNonDiscrAttributes();
2637 void MEDFileUMesh::setName(const std::string& name)
2639 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2640 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2641 (*it)->setName(name);
2642 MEDFileMesh::setName(name);
2645 MEDFileUMesh::MEDFileUMesh()
2649 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2652 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2654 catch(INTERP_KERNEL::Exception& e)
2660 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2661 * See MEDFileUMesh::LoadPartOf for detailed description.
2665 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)
2667 MEDFileUMeshL2 loaderl2;
2668 MEDCoupling::MEDCouplingMeshType meshType;
2671 MEDCoupling::MEDCouplingAxisType dummy3;
2672 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2673 if(meshType!=UNSTRUCTURED)
2675 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2676 throw INTERP_KERNEL::Exception(oss.str().c_str());
2678 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2679 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2683 * \brief Write joints in a file
2685 void MEDFileMesh::writeJoints(med_idt fid) const
2687 if ( _joints.isNotNull() )
2688 _joints->writeLL(fid);
2692 * \brief Load joints in a file or use provided ones
2694 //================================================================================
2696 * \brief Load joints in a file or use provided ones
2697 * \param [in] fid - MED file descriptor
2698 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2699 * Usually this joints are those just read by another iteration
2700 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2702 //================================================================================
2704 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2706 if ( toUseInstedOfReading )
2707 setJoints( toUseInstedOfReading );
2709 _joints = MEDFileJoints::New( fid, _name );
2712 void MEDFileMesh::loadEquivalences(med_idt fid)
2714 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2716 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2719 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2721 const MEDFileEquivalences *equiv(other._equiv);
2723 _equiv=equiv->deepCopy(this);
2726 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2728 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2729 if(!thisEq && !otherEq)
2731 if(thisEq && otherEq)
2732 return thisEq->isEqual(otherEq,what);
2735 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2740 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2742 const MEDFileEquivalences *equiv(_equiv);
2745 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2746 _equiv->getRepr(oss);
2749 void MEDFileMesh::checkCartesian() const
2751 if(getAxisType()!=AX_CART)
2753 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()) << ").";
2754 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2755 oss << " - call setAxisType(AX_CART)" << std::endl;
2756 oss << " - call cartesianize()";
2757 throw INTERP_KERNEL::Exception(oss.str().c_str());
2762 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2764 int MEDFileMesh::getNumberOfJoints() const
2766 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2770 * \brief Return joints with all adjacent mesh domains
2772 MEDFileJoints * MEDFileMesh::getJoints() const
2774 return const_cast<MEDFileJoints*>(& (*_joints));
2777 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2779 if ( joints != _joints )
2788 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2790 * \sa loadPartUMeshFromFile
2792 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2794 MEDFileUMeshL2 loaderl2;
2795 MEDCoupling::MEDCouplingMeshType meshType;
2798 MEDCoupling::MEDCouplingAxisType axType;
2799 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2800 setAxisType(axType);
2801 if(meshType!=UNSTRUCTURED)
2803 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2804 throw INTERP_KERNEL::Exception(oss.str().c_str());
2806 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2807 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2810 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2812 int lev=loaderl2.getNumberOfLevels();
2814 for(int i=0;i<lev;i++)
2816 if(!loaderl2.emptyLev(i))
2817 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2821 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2823 setName(loaderl2.getName());
2824 setDescription(loaderl2.getDescription());
2825 setUnivName(loaderl2.getUnivName());
2826 setIteration(loaderl2.getIteration());
2827 setOrder(loaderl2.getOrder());
2828 setTimeValue(loaderl2.getTime());
2829 setTimeUnit(loaderl2.getTimeUnit());
2830 _coords=loaderl2.getCoords();
2831 if(!mrs || mrs->isNodeFamilyFieldReading())
2832 _fam_coords=loaderl2.getCoordsFamily();
2833 if(!mrs || mrs->isNodeNumFieldReading())
2834 _num_coords=loaderl2.getCoordsNum();
2835 if(!mrs || mrs->isNodeNameFieldReading())
2836 _name_coords=loaderl2.getCoordsName();
2837 _part_coords=loaderl2.getPartDefOfCoo();
2841 MEDFileUMesh::~MEDFileUMesh()
2845 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2847 const DataArrayDouble *coo=_coords;
2848 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2849 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2850 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2851 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2852 int spaceDim=coo?coo->getNumberOfComponents():0;
2855 mdim=getMeshDimension();
2856 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2857 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2858 for(int i=0;i<spaceDim;i++)
2860 std::string info=coo->getInfoOnComponent(i);
2862 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2863 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
2864 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
2866 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2868 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2869 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2870 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2871 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2872 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2873 (*it)->write(fid,meshName,mdim);
2874 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2878 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2879 * \return std::vector<int> - a sequence of the relative dimensions.
2881 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2883 std::vector<int> ret;
2885 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2886 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2893 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2894 * \return std::vector<int> - a sequence of the relative dimensions.
2896 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2898 std::vector<int> ret0=getNonEmptyLevels();
2899 if((const DataArrayDouble *) _coords)
2901 std::vector<int> ret(ret0.size()+1);
2903 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2909 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2911 std::vector<int> ret;
2912 const DataArrayInt *famCoo(_fam_coords);
2916 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2918 const MEDFileUMeshSplitL1 *cur(*it);
2920 if(cur->getFamilyField())
2926 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2928 std::vector<int> ret;
2929 const DataArrayInt *numCoo(_num_coords);
2933 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2935 const MEDFileUMeshSplitL1 *cur(*it);
2937 if(cur->getNumberField())
2943 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2945 std::vector<int> ret;
2946 const DataArrayAsciiChar *nameCoo(_name_coords);
2950 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2952 const MEDFileUMeshSplitL1 *cur(*it);
2954 if(cur->getNameField())
2961 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2962 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2963 * \param [in] fams - the name of the family of interest.
2964 * \return std::vector<int> - a sequence of the relative dimensions.
2966 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2968 std::vector<int> ret;
2969 std::vector<int> levs(getNonEmptyLevels());
2970 std::vector<int> famIds(getFamiliesIds(fams));
2971 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2972 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2978 * Returns all relative mesh levels (including nodes) where given families are defined.
2979 * \param [in] fams - the names of the families of interest.
2980 * \return std::vector<int> - a sequence of the relative dimensions.
2982 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2984 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2985 const DataArrayInt *famCoords(_fam_coords);
2988 std::vector<int> famIds(getFamiliesIds(fams));
2989 if(famCoords->presenceOfValue(famIds))
2991 std::vector<int> ret(ret0.size()+1);
2993 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
3000 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3002 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3003 if((const DataArrayInt *)_fam_coords)
3005 int val=_fam_coords->getMaxValue(tmp);
3006 ret=std::max(ret,std::abs(val));
3008 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3010 if((const MEDFileUMeshSplitL1 *)(*it))
3012 const DataArrayInt *da=(*it)->getFamilyField();
3015 int val=da->getMaxValue(tmp);
3016 ret=std::max(ret,std::abs(val));
3023 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3025 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3026 if((const DataArrayInt *)_fam_coords)
3028 int val=_fam_coords->getMaxValue(tmp);
3029 ret=std::max(ret,val);
3031 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3033 if((const MEDFileUMeshSplitL1 *)(*it))
3035 const DataArrayInt *da=(*it)->getFamilyField();
3038 int val=da->getMaxValue(tmp);
3039 ret=std::max(ret,val);
3046 int MEDFileUMesh::getMinFamilyIdInArrays() const
3048 int ret=std::numeric_limits<int>::max(),tmp=-1;
3049 if((const DataArrayInt *)_fam_coords)
3051 int val=_fam_coords->getMinValue(tmp);
3052 ret=std::min(ret,val);
3054 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3056 if((const MEDFileUMeshSplitL1 *)(*it))
3058 const DataArrayInt *da=(*it)->getFamilyField();
3061 int val=da->getMinValue(tmp);
3062 ret=std::min(ret,val);
3070 * Returns the dimension on cells in \a this mesh.
3071 * \return int - the mesh dimension.
3072 * \throw If there are no cells in this mesh.
3074 int MEDFileUMesh::getMeshDimension() const
3077 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3078 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3079 return (*it)->getMeshDimension()+lev;
3080 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3084 * Returns the space dimension of \a this mesh that is equal to number of components in
3085 * the node coordinates array.
3086 * \return int - the space dimension of \a this mesh.
3087 * \throw If the node coordinates array is not available.
3089 int MEDFileUMesh::getSpaceDimension() const
3091 const DataArrayDouble *coo=_coords;
3093 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3094 return coo->getNumberOfComponents();
3098 * Returns a string describing \a this mesh.
3099 * \return std::string - the mesh information string.
3101 std::string MEDFileUMesh::simpleRepr() const
3103 std::ostringstream oss;
3104 oss << MEDFileMesh::simpleRepr();
3105 const DataArrayDouble *coo=_coords;
3106 oss << "- The dimension of the space is ";
3107 static const char MSG1[]= "*** NO COORDS SET ***";
3108 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3110 oss << _coords->getNumberOfComponents() << std::endl;
3112 oss << MSG1 << std::endl;
3113 oss << "- Type of the mesh : UNSTRUCTURED\n";
3114 oss << "- Number of nodes : ";
3116 oss << _coords->getNumberOfTuples() << std::endl;
3118 oss << MSG1 << std::endl;
3119 std::size_t nbOfLev=_ms.size();
3120 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3121 for(std::size_t i=0;i<nbOfLev;i++)
3123 const MEDFileUMeshSplitL1 *lev=_ms[i];
3124 oss << " - Level #" << -((int) i) << " has dimension : ";
3127 oss << lev->getMeshDimension() << std::endl;
3128 lev->simpleRepr(oss);
3131 oss << MSG2 << std::endl;
3133 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3136 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3137 oss << "- Names of coordinates :" << std::endl;
3138 std::vector<std::string> vars=coo->getVarsOnComponent();
3139 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3140 oss << std::endl << "- Units of coordinates : " << std::endl;
3141 std::vector<std::string> units=coo->getUnitsOnComponent();
3142 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3144 oss << std::endl << std::endl;
3146 getEquivalencesRepr(oss);
3151 * Returns a full textual description of \a this mesh.
3152 * \return std::string - the string holding the mesh description.
3154 std::string MEDFileUMesh::advancedRepr() const
3156 return simpleRepr();
3160 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3161 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3162 * \return int - the number of entities.
3163 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3165 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3167 if(meshDimRelToMaxExt==1)
3169 if(!((const DataArrayDouble *)_coords))
3170 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3171 return _coords->getNumberOfTuples();
3173 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3177 * Returns the family field for mesh entities of a given dimension.
3178 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3179 * \return const DataArrayInt * - the family field. It is an array of ids of families
3180 * each mesh entity belongs to. It can be \c NULL.
3182 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3184 if(meshDimRelToMaxExt==1)
3186 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3187 return l1->getFamilyField();
3190 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3192 if(meshDimRelToMaxExt==1)
3194 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3195 return l1->getFamilyField();
3199 * Returns the optional numbers of mesh entities of a given dimension.
3200 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3201 * \return const DataArrayInt * - the array of the entity numbers.
3202 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3204 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3206 if(meshDimRelToMaxExt==1)
3208 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3209 return l1->getNumberField();
3212 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3214 if(meshDimRelToMaxExt==1)
3215 return _name_coords;
3216 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3217 return l1->getNameField();
3221 * 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).
3223 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3224 * \param [in] gt - The input geometric type for which the part definition is requested.
3225 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3227 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3229 if(meshDimRelToMaxExt==1)
3230 return _part_coords;
3231 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3232 return l1->getPartDef(gt);
3235 int MEDFileUMesh::getNumberOfNodes() const
3237 const DataArrayDouble *coo(_coords);
3239 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3240 return coo->getNumberOfTuples();
3243 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3245 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3246 return l1->getNumberOfCells();
3249 bool MEDFileUMesh::hasImplicitPart() const
3254 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3256 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3259 void MEDFileUMesh::releaseImplicitPartIfAny() const
3263 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3265 std::size_t sz(st.getNumberOfItems());
3266 for(std::size_t i=0;i<sz;i++)
3268 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3269 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3270 if(st[i].getPflName().empty())
3271 m->computeNodeIdsAlg(nodesFetched);
3274 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3275 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3276 m2->computeNodeIdsAlg(nodesFetched);
3281 MEDFileMesh *MEDFileUMesh::cartesianize() const
3283 if(getAxisType()==AX_CART)
3286 return const_cast<MEDFileUMesh *>(this);
3290 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3291 const DataArrayDouble *coords(_coords);
3293 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3294 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3295 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3296 if((const MEDFileUMeshSplitL1 *)(*it))
3297 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3298 ret->_coords=coordsCart;
3299 ret->setAxisType(AX_CART);
3305 * Returns the optional numbers of mesh entities of a given dimension transformed using
3306 * DataArrayInt::invertArrayN2O2O2N().
3307 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3308 * \return const DataArrayInt * - the array of the entity numbers transformed using
3309 * DataArrayInt::invertArrayN2O2O2N().
3310 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3312 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3314 if(meshDimRelToMaxExt==1)
3316 if(!((const DataArrayInt *)_num_coords))
3317 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3318 return _rev_num_coords;
3320 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3321 return l1->getRevNumberField();
3325 * Returns a pointer to the node coordinates array of \a this mesh \b without
3326 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3328 DataArrayDouble *MEDFileUMesh::getCoords() const
3331 MCAuto<DataArrayDouble> tmp(_coords);
3332 if((DataArrayDouble *)tmp)
3340 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3341 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3343 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3344 * \param [in] grp - the name of the group whose mesh entities are included in the
3346 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3347 * according to the optional numbers of entities, if available.
3348 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3349 * delete this mesh using decrRef() as it is no more needed.
3350 * \throw If the name of a nonexistent group is specified.
3351 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3353 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3356 synchronizeTinyInfoOnLeaves();
3357 std::vector<std::string> tmp(1);
3359 return getGroups(meshDimRelToMaxExt,tmp,renum);
3363 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3364 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3366 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3367 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3369 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3370 * according to the optional numbers of entities, if available.
3371 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3372 * delete this mesh using decrRef() as it is no more needed.
3373 * \throw If a name of a nonexistent group is present in \a grps.
3374 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3376 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3379 synchronizeTinyInfoOnLeaves();
3380 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3381 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3382 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3383 zeRet->setName(grps[0]);
3384 return zeRet.retn();
3388 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3389 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3391 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3392 * \param [in] fam - the name of the family whose mesh entities are included in the
3394 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3395 * according to the optional numbers of entities, if available.
3396 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3397 * delete this mesh using decrRef() as it is no more needed.
3398 * \throw If a name of a nonexistent family is present in \a grps.
3399 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3401 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3404 synchronizeTinyInfoOnLeaves();
3405 std::vector<std::string> tmp(1);
3407 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3411 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3412 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3414 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3415 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3417 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3418 * according to the optional numbers of entities, if available.
3419 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3420 * delete this mesh using decrRef() as it is no more needed.
3421 * \throw If a name of a nonexistent family is present in \a fams.
3422 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3424 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3427 synchronizeTinyInfoOnLeaves();
3428 if(meshDimRelToMaxExt==1)
3430 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3431 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3432 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3436 std::vector<int> famIds=getFamiliesIds(fams);
3437 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3438 MCAuto<MEDCouplingUMesh> zeRet;
3440 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3442 zeRet=l1->getFamilyPart(0,0,renum);
3443 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3444 zeRet->setName(fams[0]);
3445 return zeRet.retn();
3449 * Returns ids of mesh entities contained in given families of a given dimension.
3450 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3452 * \param [in] fams - the names of the families of interest.
3453 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3454 * returned instead of ids.
3455 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3456 * numbers, if available and required, of mesh entities of the families. The caller
3457 * is to delete this array using decrRef() as it is no more needed.
3458 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3460 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3462 std::vector<int> famIds=getFamiliesIds(fams);
3463 if(meshDimRelToMaxExt==1)
3465 if((const DataArrayInt *)_fam_coords)
3467 MCAuto<DataArrayInt> da;
3469 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3471 da=_fam_coords->findIdsEqualList(0,0);
3473 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3478 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3480 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3482 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3484 return l1->getFamilyPartArr(0,0,renum);
3488 * Returns a MEDCouplingUMesh of a given relative dimension.
3489 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3490 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3491 * To build a valid MEDCouplingUMesh from the returned one in this case,
3492 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3493 * \param [in] meshDimRelToMax - the relative dimension of interest.
3494 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3495 * optional numbers of mesh entities.
3496 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3497 * delete using decrRef() as it is no more needed.
3498 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3500 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3503 synchronizeTinyInfoOnLeaves();
3504 if(meshDimRelToMaxExt==1)
3508 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3509 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3510 umesh->setCoords(cc);
3511 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3512 umesh->setName(getName());
3516 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3517 return l1->getWholeMesh(renum);
3520 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3522 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3523 return l1->getDistributionOfTypes();
3527 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3528 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3529 * optional numbers of mesh entities.
3530 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3531 * delete using decrRef() as it is no more needed.
3532 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3534 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3536 return getMeshAtLevel(0,renum);
3540 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3541 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3542 * optional numbers of mesh entities.
3543 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3544 * delete using decrRef() as it is no more needed.
3545 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3547 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3549 return getMeshAtLevel(-1,renum);
3553 * Returns a MEDCouplingUMesh of a relative dimension == -2.
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 == -2 in \a this mesh.
3560 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3562 return getMeshAtLevel(-2,renum);
3566 * Returns a MEDCouplingUMesh of a relative dimension == -3.
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 == -3 in \a this mesh.
3573 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3575 return getMeshAtLevel(-3,renum);
3579 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3580 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3581 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3582 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3584 void MEDFileUMesh::forceComputationOfParts() const
3586 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3588 const MEDFileUMeshSplitL1 *elt(*it);
3590 elt->forceComputationOfParts();
3595 * This method returns a vector of mesh parts containing each exactly one geometric type.
3596 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3597 * This method is only for memory aware users.
3598 * The returned pointers are **NOT** new object pointer. No need to mange them.
3600 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3603 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3604 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3608 * This method returns the part of \a this having the geometric type \a gt.
3609 * If such part is not existing an exception will be thrown.
3610 * The returned pointer is **NOT** new object pointer. No need to mange it.
3612 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3615 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3616 int lev=(int)cm.getDimension()-getMeshDimension();
3617 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3618 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3622 * This method returns for each geo types in \a this number of cells with this geo type.
3623 * 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.
3624 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3626 * \sa getDistributionOfTypes
3628 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3630 std::vector< std::pair<int,int> > ret;
3631 std::vector<int> nel(getNonEmptyLevels());
3632 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3634 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3635 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3637 int nbCells(getNumberOfCellsWithType(*it1));
3638 ret.push_back(std::pair<int,int>(*it1,nbCells));
3641 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3646 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3647 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3649 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3651 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3652 return sp->getGeoTypes();
3655 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3657 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3658 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3659 return sp->getNumberOfCellsWithType(ct);
3663 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3664 * \param [in] gt - the geometric type for which the family field is asked.
3665 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3666 * delete using decrRef() as it is no more needed.
3667 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3669 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3671 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3672 int lev=(int)cm.getDimension()-getMeshDimension();
3673 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3674 return sp->extractFamilyFieldOnGeoType(gt);
3678 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3679 * \param [in] gt - the geometric type for which the number field is asked.
3680 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3681 * delete using decrRef() as it is no more needed.
3682 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3684 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3686 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3687 int lev=(int)cm.getDimension()-getMeshDimension();
3688 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3689 return sp->extractNumberFieldOnGeoType(gt);
3693 * This method returns for specified geometric type \a gt the relative level to \a this.
3694 * If the relative level is empty an exception will be thrown.
3696 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3698 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3699 int ret((int)cm.getDimension()-getMeshDimension());
3700 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3704 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3706 if(meshDimRelToMaxExt==1)
3707 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3708 if(meshDimRelToMaxExt>1)
3709 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3710 int tracucedRk=-meshDimRelToMaxExt;
3711 if(tracucedRk>=(int)_ms.size())
3712 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3713 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3714 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3715 return _ms[tracucedRk];
3718 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3720 if(meshDimRelToMaxExt==1)
3721 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3722 if(meshDimRelToMaxExt>1)
3723 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3724 int tracucedRk=-meshDimRelToMaxExt;
3725 if(tracucedRk>=(int)_ms.size())
3726 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3727 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3728 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3729 return _ms[tracucedRk];
3732 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3734 if(-meshDimRelToMax>=(int)_ms.size())
3735 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3737 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3739 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3741 int ref=(*it)->getMeshDimension();
3742 if(ref+i!=meshDim-meshDimRelToMax)
3743 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3749 * Sets the node coordinates array of \a this mesh.
3750 * \param [in] coords - the new node coordinates array.
3751 * \throw If \a coords == \c NULL.
3753 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3756 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3757 if(coords==(DataArrayDouble *)_coords)
3759 coords->checkAllocated();
3760 int nbOfTuples(coords->getNumberOfTuples());
3763 _fam_coords=DataArrayInt::New();
3764 _fam_coords->alloc(nbOfTuples,1);
3765 _fam_coords->fillWithZero();
3766 _num_coords=0; _rev_num_coords=0; _name_coords=0;
3767 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3768 if((MEDFileUMeshSplitL1 *)(*it))
3769 (*it)->setCoords(coords);
3773 * Change coords without changing anything concerning families and numbering on nodes.
3775 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3778 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3779 if(coords==(DataArrayDouble *)_coords)
3781 coords->checkAllocated();
3782 int nbOfTuples(coords->getNumberOfTuples());
3783 if(_coords.isNull())
3790 int oldNbTuples(_coords->getNumberOfTuples());
3791 if(oldNbTuples!=nbOfTuples)
3792 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3796 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3797 if((MEDFileUMeshSplitL1 *)(*it))
3798 (*it)->setCoords(coords);
3802 * Removes all groups of a given dimension in \a this mesh.
3803 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3804 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3806 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3808 if(meshDimRelToMaxExt==1)
3810 if((DataArrayInt *)_fam_coords)
3811 _fam_coords->fillWithZero();
3814 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3815 l1->eraseFamilyField();
3820 * Removes all families with ids not present in the family fields of \a this mesh.
3822 void MEDFileUMesh::optimizeFamilies()
3824 std::vector<int> levs=getNonEmptyLevelsExt();
3825 std::set<int> allFamsIds;
3826 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3828 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3829 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3831 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3834 std::set<std::string> famNamesToKill;
3835 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3837 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3838 famNamesToKill.insert((*it).first);
3840 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3841 _families.erase(*it);
3842 std::vector<std::string> grpNamesToKill;
3843 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3845 std::vector<std::string> tmp;
3846 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3848 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3849 tmp.push_back(*it2);
3854 tmp.push_back((*it).first);
3856 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3861 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3862 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3863 * The boundary is built according to the following method:
3864 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3865 * coordinates array is extended).
3866 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3867 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3868 * might not be duplicated at all.
3869 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3870 * other side of the group is no more a neighbor)
3871 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3872 * bordering the newly created boundary use the newly computed nodes.
3873 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3874 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3876 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3877 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3879 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3880 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3881 * \sa clearNodeAndCellNumbers()
3883 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3884 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3886 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3887 typedef MCAuto<DataArrayInt> DAInt;
3889 std::vector<int> levs=getNonEmptyLevels();
3890 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3891 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3892 MUMesh m0=getMeshAtLevel(0);
3893 MUMesh m1=getMeshAtLevel(-1);
3894 int nbNodes=m0->getNumberOfNodes();
3895 MUMesh m11=getGroup(-1,grpNameM1);
3896 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3897 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3898 DAInt nodeIdsToDuplicate(tmp00);
3899 DAInt cellsToModifyConn0(tmp11);
3900 DAInt cellsToModifyConn1(tmp22);
3901 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3902 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3903 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3904 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3905 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3906 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3907 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3908 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3909 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3910 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3911 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3912 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3913 DAInt grpIds=getGroupArr(-1,grpNameM1);
3914 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3915 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3916 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3917 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3918 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3919 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3920 m0->setCoords(tmp0->getCoords());
3921 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3922 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3923 m1->setCoords(m0->getCoords());
3924 _coords=m0->getCoords(); _coords->incrRef();
3925 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3926 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3927 DataArrayInt * duplCells;
3928 m1->areCellsIncludedIn(m11, 0, duplCells);
3929 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3930 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3931 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3932 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3933 DAInt szOfCellGrpOfSameType(tmp00);
3934 DAInt idInMsOfCellGrpOfSameType(tmp11);
3936 newm1->setName(getName());
3937 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3939 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3940 DAInt newFam=DataArrayInt::New();
3941 newFam->alloc(newm1->getNumberOfCells(),1);
3942 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3943 // Positive ID for family of nodes, negative for all the rest.
3945 if (m1->getMeshDimension() == 0)
3946 idd=getMaxFamilyId()+1;
3948 idd=getMinFamilyId()-1;
3949 int globStart=0,start=0,end,globEnd;
3950 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3951 for(int i=0;i<nbOfChunks;i++)
3953 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3954 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3956 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3957 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3958 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3963 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3967 newm1->setCoords(getCoords());
3968 setMeshAtLevel(-1,newm1);
3969 setFamilyFieldArr(-1,newFam);
3970 std::string grpName2(grpNameM1); grpName2+="_dup";
3971 addFamily(grpName2,idd);
3972 addFamilyOnGrp(grpName2,grpName2);
3977 int newNbOfNodes=getCoords()->getNumberOfTuples();
3978 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3979 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3980 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3985 _rev_num_coords = 0;
3986 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
3987 it != _ms.end(); it++)
3990 (*it)->_rev_num = 0;
3992 nodesDuplicated=nodeIdsToDuplicate.retn();
3993 cellsModified=cellsToModifyConn0.retn();
3994 cellsNotModified=cellsToModifyConn1.retn();
3997 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
3998 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4001 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4002 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4003 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4005 * \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.
4006 * 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.
4008 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4010 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4011 std::vector<int> levs=getNonEmptyLevels();
4013 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4014 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4017 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4019 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4020 std::vector<int> code1=m->getDistributionOfTypes();
4021 end=PutInThirdComponentOfCodeOffset(code1,start);
4022 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4023 bool hasChanged=m->unPolyze();
4024 DataArrayInt *fake=0;
4025 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4026 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4028 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4031 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4032 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4034 MCAuto<DataArrayInt> famField2,numField2;
4035 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4036 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4037 setMeshAtLevel(*it,m);
4038 std::vector<int> code2=m->getDistributionOfTypes();
4039 end=PutInThirdComponentOfCodeOffset(code2,start);
4040 newCode.insert(newCode.end(),code2.begin(),code2.end());
4042 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4046 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4047 setFamilyFieldArr(*it,newFamField);
4051 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4052 setRenumFieldArr(*it,newNumField);
4057 newCode.insert(newCode.end(),code1.begin(),code1.end());
4063 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4064 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4065 o2nRenumCell=o2nRenumCellRet.retn();
4070 /*! \cond HIDDEN_ITEMS */
4071 struct MEDLoaderAccVisit1
4073 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4074 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4075 int _new_nb_of_nodes;
4080 * 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.
4081 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4082 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4083 * -1 values in returned array means that the corresponding old node is no more used.
4085 * \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
4086 * is modified in \a this.
4087 * \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
4090 DataArrayInt *MEDFileUMesh::zipCoords()
4092 const DataArrayDouble *coo(getCoords());
4094 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4095 int nbOfNodes(coo->getNumberOfTuples());
4096 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4097 std::vector<int> neLevs(getNonEmptyLevels());
4098 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4100 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4101 if(zeLev->isMeshStoredSplitByType())
4103 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4104 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4106 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4110 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4111 mesh->computeNodeIdsAlg(nodeIdsInUse);
4114 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4115 if(nbrOfNodesInUse==nbOfNodes)
4116 return 0;//no need to update _part_coords
4117 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4118 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4119 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4120 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4121 MCAuto<DataArrayInt> newFamCoords;
4122 MCAuto<DataArrayAsciiChar> newNameCoords;
4123 if((const DataArrayInt *)_fam_coords)
4124 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4125 MCAuto<DataArrayInt> newNumCoords;
4126 if((const DataArrayInt *)_num_coords)
4127 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4128 if((const DataArrayAsciiChar *)_name_coords)
4129 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4130 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4131 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4133 if((MEDFileUMeshSplitL1*)*it)
4135 (*it)->renumberNodesInConn(ret->begin());
4136 (*it)->setCoords(_coords);
4139 // updates _part_coords
4140 const PartDefinition *pc(_part_coords);
4143 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4144 _part_coords=tmpPD->composeWith(pc);
4150 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4151 * The extraction of \a this is specified by the extractDef \a input map.
4152 * This map tells for each level of cells, the cells kept in the extraction.
4154 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4155 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4157 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4159 std::vector<int> levs(getNonEmptyLevels());
4160 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4161 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4164 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4165 if((*it).second.isNull())
4166 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4169 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4171 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4172 throw INTERP_KERNEL::Exception(oss.str());
4174 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4175 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4176 mPart->computeNodeIdsAlg(fetchedNodes);
4178 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4182 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4184 * \return - a new reference of MEDFileUMesh
4185 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4187 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4189 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4190 std::vector<int> levs(getNonEmptyLevels());
4191 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4194 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4195 if((*it).second.isNull())
4196 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4199 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4201 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4202 throw INTERP_KERNEL::Exception(oss.str());
4204 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4205 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4206 ret->setMeshAtLevel((*it).first,mPart);
4207 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4210 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4211 ret->setFamilyFieldArr((*it).first,famPart);
4215 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4216 ret->setFamilyFieldArr((*it).first,numPart);
4219 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4220 if(it2!=extractDef.end())
4222 const DataArrayDouble *coo(ret->getCoords());
4224 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4225 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4226 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4227 ret->setCoords(cooPart);
4228 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4231 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4232 ret->setFamilyFieldArr(1,famPart);
4236 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4237 ret->setFamilyFieldArr(1,numPart);
4239 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4243 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4244 m->renumberNodesInConn(o2nNodes->begin());
4245 ret->setMeshAtLevel((*it3).first,m);
4252 * This method performs an extrusion along a path defined by \a m1D.
4253 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4254 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4255 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4256 * This method scans all levels in \a this
4257 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4259 * \param [in] m1D - the mesh defining the extrusion path.
4260 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4261 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4263 * \sa MEDCouplingUMesh::buildExtrudedMesh
4265 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4268 if(getMeshDimension()!=2)
4269 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4270 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4271 m1D->checkConsistencyLight();
4272 if(m1D->getMeshDimension()!=1)
4273 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4274 int nbRep(m1D->getNumberOfCells());
4275 std::vector<int> levs(getNonEmptyLevels());
4276 std::vector<std::string> grps(getGroupsNames());
4277 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4278 DataArrayDouble *coords(0);
4279 std::size_t nbOfLevsOut(levs.size()+1);
4280 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4281 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4283 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4284 item=item->clone(false);
4285 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4286 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4287 tmp->changeSpaceDimension(3+(*lev),0.);
4288 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4289 zeList.push_back(elt);
4291 coords=elt->getCoords();
4294 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4295 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4297 (*it)->setName(getName());
4298 (*it)->setCoords(coords);
4300 for(std::size_t ii=0;ii!=zeList.size();ii++)
4303 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4306 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4307 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4308 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4309 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4310 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4311 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4312 std::vector<const MEDCouplingUMesh *> elts(3);
4313 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4314 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4315 elt->setName(getName());
4318 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4319 ret->setMeshAtLevel(lev,elt);
4321 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4322 endLev=endLev->clone(false); endLev->setCoords(coords);
4323 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4324 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4325 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4326 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4327 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4328 endLev->setName(getName());
4329 ret->setMeshAtLevel(levs.back()-1,endLev);
4331 for(std::size_t ii=0;ii!=zeList.size();ii++)
4334 std::vector< MCAuto<DataArrayInt> > outGrps;
4335 std::vector< const DataArrayInt * > outGrps2;
4338 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4340 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4341 if(!grpArr->empty())
4343 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4344 int offset0(zeList[ii]->getNumberOfCells());
4345 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4346 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4347 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4348 grpArr2->setName(oss.str());
4349 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4350 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4351 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4352 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4357 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4359 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4360 if(!grpArr->empty())
4362 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4363 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4364 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4365 for(int iii=0;iii<nbRep;iii++)
4367 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4368 grpArrs2[iii]=grpArrs[iii];
4370 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4371 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4372 std::ostringstream grpName; grpName << *grp << "_extruded";
4373 grpArrExt->setName(grpName.str());
4374 outGrps.push_back(grpArrExt);
4375 outGrps2.push_back(grpArrExt);
4378 ret->setGroupsAtLevel(lev,outGrps2);
4380 std::vector< MCAuto<DataArrayInt> > outGrps;
4381 std::vector< const DataArrayInt * > outGrps2;
4382 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4384 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4385 if(grpArr1->empty())
4387 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4388 std::ostringstream grpName; grpName << *grp << "_top";
4389 grpArr2->setName(grpName.str());
4390 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4391 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4392 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4394 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4399 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4400 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4401 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4403 * \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
4404 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4405 * \param [in] eps - detection threshold for coordinates.
4406 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4408 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4410 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4413 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4414 int initialNbNodes(getNumberOfNodes());
4415 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4416 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4418 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4420 DataArrayDouble *zeCoords(m0->getCoords());
4421 ret->setMeshAtLevel(0,m0);
4422 std::vector<int> levs(getNonEmptyLevels());
4423 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4426 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4427 ret->setFamilyFieldArr(0,famFieldCpy);
4429 famField=getFamilyFieldAtLevel(1);
4432 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4433 fam->fillWithZero();
4434 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4435 ret->setFamilyFieldArr(1,fam);
4437 ret->copyFamGrpMapsFrom(*this);
4438 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4439 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4443 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4444 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4445 if(m1->getMeshDimension()!=0)
4448 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4449 }//kill unused notUsed var
4450 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4452 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4453 MCAuto<DataArrayInt> bSafe(b);
4456 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4457 throw INTERP_KERNEL::Exception(oss.str().c_str());
4459 b->applyLin(1,initialNbNodes);
4460 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4461 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4462 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4463 m1->renumberNodesInConn(renum->begin());
4465 m1->setCoords(zeCoords);
4466 ret->setMeshAtLevel(*lev,m1);
4467 famField=getFamilyFieldAtLevel(*lev);
4470 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4471 ret->setFamilyFieldArr(*lev,famFieldCpy);
4478 * This method converts all quadratic cells in \a this into linear cells.
4479 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4480 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4482 * \param [in] eps - detection threshold for coordinates.
4483 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4485 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4487 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4490 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4491 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4492 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4493 m0->convertQuadraticCellsToLinear();
4495 DataArrayDouble *zeCoords(m0->getCoords());
4496 ret->setMeshAtLevel(0,m0);
4497 std::vector<int> levs(getNonEmptyLevels());
4498 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4501 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4502 ret->setFamilyFieldArr(0,famFieldCpy);
4504 famField=getFamilyFieldAtLevel(1);
4507 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4508 ret->setFamilyFieldArr(1,fam);
4510 ret->copyFamGrpMapsFrom(*this);
4511 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4515 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4516 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4517 m1->convertQuadraticCellsToLinear();
4520 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4521 MCAuto<DataArrayInt> bSafe(b);
4524 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4525 throw INTERP_KERNEL::Exception(oss.str().c_str());
4527 m1->renumberNodesInConn(b->begin());
4528 m1->setCoords(zeCoords);
4529 ret->setMeshAtLevel(*lev,m1);
4530 famField=getFamilyFieldAtLevel(*lev);
4533 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4534 ret->setFamilyFieldArr(*lev,famFieldCpy);
4541 * Computes the symmetry of \a this.
4542 * \return a new object.
4544 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4546 MCAuto<MEDFileUMesh> ret(deepCopy());
4547 DataArrayDouble *myCoo(getCoords());
4550 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4551 ret->setCoordsForced(newCoo);
4556 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4559 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4560 std::size_t sz(meshes.size()),i(0);
4561 std::vector<const DataArrayDouble *> coos(sz);
4562 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4563 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4566 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4567 coos[i]=(*it)->getCoords();
4568 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4569 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4571 const MEDFileUMesh *ref(meshes[0]);
4572 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4573 std::vector<int> levs(ref->getNonEmptyLevels());
4574 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4575 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4576 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4577 std::map<std::string,int> map1;
4578 std::map<std::string, std::vector<std::string> > map2;
4579 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4581 if((*it)->getSpaceDimension()!=spaceDim)
4582 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4583 if((*it)->getMeshDimension()!=meshDim)
4584 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4585 if((*it)->getNonEmptyLevels()!=levs)
4586 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4587 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4589 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4590 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4591 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4592 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4594 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4595 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4596 map1[(*it3).first]=(*it3).second;
4597 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4598 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4599 map2[(*it4).first]=(*it4).second;
4601 // Easy part : nodes
4602 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4603 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4604 ret->setCoords(coo);
4605 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4607 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4608 ret->setFamilyFieldArr(1,fam_coo);
4610 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4612 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4613 ret->setRenumFieldArr(1,num_coo);
4616 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4618 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4619 if(it2==m_mesh.end())
4620 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4621 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4622 mesh->setCoords(coo); mesh->setName(ref->getName());
4623 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4624 ret->setMeshAtLevel(*it,mesh);
4625 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4626 if(it3!=m_fam.end())
4628 const std::vector<const DataArrayInt *>& fams((*it3).second);
4629 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4631 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4632 famm->renumberInPlace(renum->begin());
4633 ret->setFamilyFieldArr(*it,famm);
4636 if(it4!=m_renum.end())
4638 const std::vector<const DataArrayInt *>& renums((*it4).second);
4639 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4641 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4642 renumm->renumberInPlace(renum->begin());
4643 ret->setRenumFieldArr(*it,renumm);
4648 ret->setFamilyInfo(map1);
4649 ret->setGroupInfo(map2);
4650 ret->setName(ref->getName());
4654 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4656 if(getMeshDimension()!=3)
4657 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4658 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4659 if(m3D.isNull() || m2D.isNull())
4660 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4661 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4662 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4666 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4668 clearNonDiscrAttributes();
4669 forceComputationOfParts();
4670 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4671 std::vector<int> layer0;
4672 layer0.push_back(getAxisType());//0 i
4673 layer0.push_back(_order); //1 i
4674 layer0.push_back(_iteration);//2 i
4675 layer0.push_back(getSpaceDimension());//3 i
4676 tinyDouble.push_back(_time);//0 d
4677 tinyStr.push_back(_name);//0 s
4678 tinyStr.push_back(_desc_name);//1 s
4679 for(int i=0;i<getSpaceDimension();i++)
4680 tinyStr.push_back(_coords->getInfoOnComponent(i));
4681 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4682 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4684 tinyStr.push_back((*it).first);
4685 layer0.push_back((*it).second);
4687 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4688 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4690 layer0.push_back((int)(*it0).second.size());
4691 tinyStr.push_back((*it0).first);
4692 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4693 tinyStr.push_back(*it1);
4695 // sizeof(layer0)==4+aa+1+bb layer#0
4696 bigArrayD=_coords;// 0 bd
4697 bigArraysI.push_back(_fam_coords);// 0 bi
4698 bigArraysI.push_back(_num_coords);// 1 bi
4699 const PartDefinition *pd(_part_coords);
4701 layer0.push_back(-1);
4704 std::vector<int> tmp0;
4705 pd->serialize(tmp0,bigArraysI);
4706 tinyInt.push_back(tmp0.size());
4707 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4710 std::vector<int> layer1;
4711 std::vector<int> levs(getNonEmptyLevels());
4712 layer1.push_back((int)levs.size());// 0 i <- key
4713 layer1.insert(layer1.end(),levs.begin(),levs.end());
4714 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4716 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4717 lev->serialize(layer1,bigArraysI);
4719 // put layers all together.
4720 tinyInt.push_back(layer0.size());
4721 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4722 tinyInt.push_back(layer1.size());
4723 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4726 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4727 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4729 int sz0(tinyInt[0]);
4730 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4731 int sz1(tinyInt[sz0+1]);
4732 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4734 std::reverse(layer0.begin(),layer0.end());
4735 std::reverse(layer1.begin(),layer1.end());
4736 std::reverse(tinyDouble.begin(),tinyDouble.end());
4737 std::reverse(tinyStr.begin(),tinyStr.end());
4738 std::reverse(bigArraysI.begin(),bigArraysI.end());
4740 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4741 _order=layer0.back(); layer0.pop_back();
4742 _iteration=layer0.back(); layer0.pop_back();
4743 int spaceDim(layer0.back()); layer0.pop_back();
4744 _time=tinyDouble.back(); tinyDouble.pop_back();
4745 _name=tinyStr.back(); tinyStr.pop_back();
4746 _desc_name=tinyStr.back(); tinyStr.pop_back();
4747 _coords=bigArrayD; _coords->rearrange(spaceDim);
4748 for(int i=0;i<spaceDim;i++)
4750 _coords->setInfoOnComponent(i,tinyStr.back());
4753 int nbOfFams(layer0.back()); layer0.pop_back();
4755 for(int i=0;i<nbOfFams;i++)
4757 _families[tinyStr.back()]=layer0.back();
4758 tinyStr.pop_back(); layer0.pop_back();
4760 int nbGroups(layer0.back()); layer0.pop_back();
4762 for(int i=0;i<nbGroups;i++)
4764 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4765 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4766 std::vector<std::string> fams(nbOfFamsOnGrp);
4767 for(int j=0;j<nbOfFamsOnGrp;j++)
4769 fams[j]=tinyStr.back(); tinyStr.pop_back();
4771 _groups[grpName]=fams;
4773 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4774 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4776 int isPd(layer0.back()); layer0.pop_back();
4779 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4780 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4781 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4784 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4786 int nbLevs(layer1.back()); layer1.pop_back();
4787 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4789 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4790 _ms.resize(maxLev+1);
4791 for(int i=0;i<nbLevs;i++)
4795 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4800 * Adds a group of nodes to \a this mesh.
4801 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4802 * The ids should be sorted and different each other (MED file norm).
4804 * \warning this method can alter default "FAMILLE_ZERO" family.
4805 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4807 * \throw If the node coordinates array is not set.
4808 * \throw If \a ids == \c NULL.
4809 * \throw If \a ids->getName() == "".
4810 * \throw If \a ids does not respect the MED file norm.
4811 * \throw If a group with name \a ids->getName() already exists.
4813 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4815 const DataArrayDouble *coords(_coords);
4817 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4818 int nbOfNodes(coords->getNumberOfTuples());
4819 if(!((DataArrayInt *)_fam_coords))
4820 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4822 addGroupUnderground(true,ids,_fam_coords);
4826 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4828 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4829 * The ids should be sorted and different each other (MED file norm).
4831 * \warning this method can alter default "FAMILLE_ZERO" family.
4832 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4834 * \throw If the node coordinates array is not set.
4835 * \throw If \a ids == \c NULL.
4836 * \throw If \a ids->getName() == "".
4837 * \throw If \a ids does not respect the MED file norm.
4838 * \throw If a group with name \a ids->getName() already exists.
4840 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4842 std::vector<int> levs(getNonEmptyLevelsExt());
4843 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4845 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4846 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4848 if(meshDimRelToMaxExt==1)
4849 { addNodeGroup(ids); return ; }
4850 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4851 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4852 addGroupUnderground(false,ids,fam);
4856 * Changes a name of a family specified by its id.
4857 * \param [in] id - the id of the family of interest.
4858 * \param [in] newFamName - the new family name.
4859 * \throw If no family with the given \a id exists.
4861 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4863 std::string oldName=getFamilyNameGivenId(id);
4864 _families.erase(oldName);
4865 _families[newFamName]=id;
4869 * Removes a mesh of a given dimension.
4870 * \param [in] meshDimRelToMax - the relative dimension of interest.
4871 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4873 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4875 std::vector<int> levSet=getNonEmptyLevels();
4876 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4877 if(it==levSet.end())
4878 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4879 int pos=(-meshDimRelToMax);
4884 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4885 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4886 * \param [in] m - the new mesh to set.
4887 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4889 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4890 * another node coordinates array.
4891 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4892 * to the existing meshes of other levels of \a this mesh.
4894 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4896 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4897 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4901 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4902 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4903 * \param [in] m - the new mesh to set.
4904 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4905 * writing \a this mesh in a MED file.
4906 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4908 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4909 * another node coordinates array.
4910 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4911 * to the existing meshes of other levels of \a this mesh.
4913 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4915 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4916 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4919 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4921 dealWithTinyInfo(m);
4922 std::vector<int> levSet=getNonEmptyLevels();
4923 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4925 if((DataArrayDouble *)_coords==0)
4927 DataArrayDouble *c=m->getCoords();
4932 if(m->getCoords()!=_coords)
4933 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4934 int sz=(-meshDimRelToMax)+1;
4935 if(sz>=(int)_ms.size())
4937 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4941 return _ms[-meshDimRelToMax];
4945 * This method allows to set at once the content of different levels in \a this.
4946 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4948 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4949 * \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.
4950 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4952 * \throw If \a there is a null pointer in \a ms.
4953 * \sa MEDFileUMesh::setMeshAtLevel
4955 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4959 const MEDCouplingUMesh *mRef=ms[0];
4961 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4962 std::string name(mRef->getName());
4963 const DataArrayDouble *coo(mRef->getCoords());
4966 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4968 const MEDCouplingUMesh *cur(*it);
4970 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4971 if(coo!=cur->getCoords())
4972 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4973 int mdim=cur->getMeshDimension();
4974 zeDim=std::max(zeDim,mdim);
4975 if(s.find(mdim)!=s.end())
4976 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4978 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4980 int mdim=(*it)->getMeshDimension();
4981 setName((*it)->getName());
4982 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4988 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4989 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4990 * The given meshes must share the same node coordinates array.
4991 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4992 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4993 * create in \a this mesh.
4994 * \throw If \a ms is empty.
4995 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4996 * to the existing meshes of other levels of \a this mesh.
4997 * \throw If the meshes in \a ms do not share the same node coordinates array.
4998 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4999 * of the given meshes.
5000 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5001 * \throw If names of some meshes in \a ms are equal.
5002 * \throw If \a ms includes a mesh with an empty name.
5004 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5007 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5008 int sz=(-meshDimRelToMax)+1;
5009 if(sz>=(int)_ms.size())
5011 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5012 DataArrayDouble *coo=checkMultiMesh(ms);
5013 if((DataArrayDouble *)_coords==0)
5019 if((DataArrayDouble *)_coords!=coo)
5020 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5021 std::vector<DataArrayInt *> corr;
5022 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5023 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5024 setMeshAtLevel(meshDimRelToMax,m,renum);
5025 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5026 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5030 * Creates groups at a given level in \a this mesh from a sequence of
5031 * meshes each representing a group.
5032 * The given meshes must share the same node coordinates array.
5033 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5034 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5035 * create in \a this mesh.
5036 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5038 * \throw If \a ms is empty.
5039 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5040 * to the existing meshes of other levels of \a this mesh.
5041 * \throw If the meshes in \a ms do not share the same node coordinates array.
5042 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5043 * of the given meshes.
5044 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5045 * \throw If names of some meshes in \a ms are equal.
5046 * \throw If \a ms includes a mesh with an empty name.
5048 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5051 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5052 int sz=(-meshDimRelToMax)+1;
5053 if(sz>=(int)_ms.size())
5055 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5056 DataArrayDouble *coo=checkMultiMesh(ms);
5057 if((DataArrayDouble *)_coords==0)
5063 if((DataArrayDouble *)_coords!=coo)
5064 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5065 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5066 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5068 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5070 DataArrayInt *arr=0;
5071 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5075 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5076 throw INTERP_KERNEL::Exception(oss.str().c_str());
5079 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5080 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5083 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5085 const DataArrayDouble *ret=ms[0]->getCoords();
5086 int mdim=ms[0]->getMeshDimension();
5087 for(unsigned int i=1;i<ms.size();i++)
5089 ms[i]->checkConsistencyLight();
5090 if(ms[i]->getCoords()!=ret)
5091 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5092 if(ms[i]->getMeshDimension()!=mdim)
5093 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5095 return const_cast<DataArrayDouble *>(ret);
5099 * Sets the family field of a given relative dimension.
5100 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5101 * the family field is set.
5102 * \param [in] famArr - the array of the family field.
5103 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5104 * \throw If \a famArr has an invalid size.
5106 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5108 if(meshDimRelToMaxExt==1)
5115 DataArrayDouble *coo(_coords);
5117 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5118 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5123 if(meshDimRelToMaxExt>1)
5124 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5125 int traducedRk=-meshDimRelToMaxExt;
5126 if(traducedRk>=(int)_ms.size())
5127 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5128 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5129 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5130 return _ms[traducedRk]->setFamilyArr(famArr);
5134 * Sets the optional numbers of mesh entities of a given dimension.
5135 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5136 * \param [in] renumArr - the array of the numbers.
5137 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5138 * \throw If \a renumArr has an invalid size.
5140 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5142 if(meshDimRelToMaxExt==1)
5150 DataArrayDouble *coo(_coords);
5152 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5153 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5154 renumArr->incrRef();
5155 _num_coords=renumArr;
5159 if(meshDimRelToMaxExt>1)
5160 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5161 int traducedRk=-meshDimRelToMaxExt;
5162 if(traducedRk>=(int)_ms.size())
5163 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5164 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5165 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5166 return _ms[traducedRk]->setRenumArr(renumArr);
5170 * Sets the optional names of mesh entities of a given dimension.
5171 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5172 * \param [in] nameArr - the array of the names.
5173 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5174 * \throw If \a nameArr has an invalid size.
5176 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5178 if(meshDimRelToMaxExt==1)
5185 DataArrayDouble *coo(_coords);
5187 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5188 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5190 _name_coords=nameArr;
5193 if(meshDimRelToMaxExt>1)
5194 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5195 int traducedRk=-meshDimRelToMaxExt;
5196 if(traducedRk>=(int)_ms.size())
5197 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5198 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5199 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5200 return _ms[traducedRk]->setNameArr(nameArr);
5203 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5205 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5206 if((const MEDFileUMeshSplitL1 *)(*it))
5207 (*it)->synchronizeTinyInfo(*this);
5211 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5213 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5215 DataArrayInt *arr=_fam_coords;
5217 arr->changeValue(oldId,newId);
5218 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5220 MEDFileUMeshSplitL1 *sp=(*it);
5223 sp->changeFamilyIdArr(oldId,newId);
5228 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5230 std::list< MCAuto<DataArrayInt> > ret;
5231 const DataArrayInt *da(_fam_coords);
5233 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5234 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5236 const MEDFileUMeshSplitL1 *elt(*it);
5239 da=elt->getFamilyField();
5241 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5247 void MEDFileUMesh::computeRevNum() const
5249 if((const DataArrayInt *)_num_coords)
5252 int maxValue=_num_coords->getMaxValue(pos);
5253 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5257 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5259 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5262 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5264 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5265 ret.push_back((const DataArrayInt *)_fam_nodes);
5266 ret.push_back((const DataArrayInt *)_num_nodes);
5267 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5268 ret.push_back((const DataArrayInt *)_fam_cells);
5269 ret.push_back((const DataArrayInt *)_num_cells);
5270 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5271 ret.push_back((const DataArrayInt *)_fam_faces);
5272 ret.push_back((const DataArrayInt *)_num_faces);
5273 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5274 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5275 ret.push_back((const DataArrayInt *)_rev_num_cells);
5276 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5280 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5282 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5283 if((const DataArrayInt *)_fam_nodes)
5285 int val=_fam_nodes->getMaxValue(tmp);
5286 ret=std::max(ret,std::abs(val));
5288 if((const DataArrayInt *)_fam_cells)
5290 int val=_fam_cells->getMaxValue(tmp);
5291 ret=std::max(ret,std::abs(val));
5293 if((const DataArrayInt *)_fam_faces)
5295 int val=_fam_faces->getMaxValue(tmp);
5296 ret=std::max(ret,std::abs(val));
5301 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5303 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5304 if((const DataArrayInt *)_fam_nodes)
5306 int val=_fam_nodes->getMaxValue(tmp);
5307 ret=std::max(ret,val);
5309 if((const DataArrayInt *)_fam_cells)
5311 int val=_fam_cells->getMaxValue(tmp);
5312 ret=std::max(ret,val);
5314 if((const DataArrayInt *)_fam_faces)
5316 int val=_fam_faces->getMaxValue(tmp);
5317 ret=std::max(ret,val);
5322 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5324 int ret=std::numeric_limits<int>::max(),tmp=-1;
5325 if((const DataArrayInt *)_fam_nodes)
5327 int val=_fam_nodes->getMinValue(tmp);
5328 ret=std::min(ret,val);
5330 if((const DataArrayInt *)_fam_cells)
5332 int val=_fam_cells->getMinValue(tmp);
5333 ret=std::min(ret,val);
5335 if((const DataArrayInt *)_fam_faces)
5337 int val=_fam_faces->getMinValue(tmp);
5338 ret=std::min(ret,val);
5343 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5345 if(!MEDFileMesh::isEqual(other,eps,what))
5347 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5350 what="Mesh types differ ! This is structured and other is NOT !";
5353 const DataArrayInt *famc1=_fam_nodes;
5354 const DataArrayInt *famc2=otherC->_fam_nodes;
5355 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5357 what="Mismatch of families arr on nodes ! One is defined and not other !";
5362 bool ret=famc1->isEqual(*famc2);
5365 what="Families arr on nodes differ !";
5370 famc2=otherC->_fam_cells;
5371 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5373 what="Mismatch of families arr on cells ! One is defined and not other !";
5378 bool ret=famc1->isEqual(*famc2);
5381 what="Families arr on cells differ !";
5386 famc2=otherC->_fam_faces;
5387 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5389 what="Mismatch of families arr on faces ! One is defined and not other !";
5394 bool ret=famc1->isEqual(*famc2);
5397 what="Families arr on faces differ !";
5402 famc2=otherC->_num_nodes;
5403 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5405 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5410 bool ret=famc1->isEqual(*famc2);
5413 what="Numbering arr on nodes differ !";
5418 famc2=otherC->_num_cells;
5419 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5421 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5426 bool ret=famc1->isEqual(*famc2);
5429 what="Numbering arr on cells differ !";
5434 famc2=otherC->_num_faces;
5435 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5437 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5442 bool ret=famc1->isEqual(*famc2);
5445 what="Numbering arr on faces differ !";
5449 const DataArrayAsciiChar *d1=_names_cells;
5450 const DataArrayAsciiChar *d2=otherC->_names_cells;
5451 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5453 what="Mismatch of naming arr on cells ! One is defined and not other !";
5458 bool ret=d1->isEqual(*d2);
5461 what="Naming arr on cells differ !";
5466 d2=otherC->_names_faces;
5467 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5469 what="Mismatch of naming arr on faces ! One is defined and not other !";
5474 bool ret=d1->isEqual(*d2);
5477 what="Naming arr on faces differ !";
5482 d2=otherC->_names_nodes;
5483 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5485 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5490 bool ret=d1->isEqual(*d2);
5493 what="Naming arr on nodes differ !";
5500 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5502 MEDFileMesh::clearNonDiscrAttributes();
5503 const DataArrayInt *tmp=_fam_nodes;
5505 (const_cast<DataArrayInt *>(tmp))->setName("");
5508 (const_cast<DataArrayInt *>(tmp))->setName("");
5511 (const_cast<DataArrayInt *>(tmp))->setName("");
5514 (const_cast<DataArrayInt *>(tmp))->setName("");
5517 (const_cast<DataArrayInt *>(tmp))->setName("");
5520 (const_cast<DataArrayInt *>(tmp))->setName("");
5524 * Returns ids of mesh entities contained in given families of a given dimension.
5525 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5527 * \param [in] fams - the names of the families of interest.
5528 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5529 * returned instead of ids.
5530 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5531 * numbers, if available and required, of mesh entities of the families. The caller
5532 * is to delete this array using decrRef() as it is no more needed.
5533 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5535 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5537 std::vector<int> famIds(getFamiliesIds(fams));
5538 switch(meshDimRelToMaxExt)
5542 if((const DataArrayInt *)_fam_nodes)
5544 MCAuto<DataArrayInt> da;
5546 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5548 da=_fam_nodes->findIdsEqualList(0,0);
5550 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5555 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5560 if((const DataArrayInt *)_fam_cells)
5562 MCAuto<DataArrayInt> da;
5564 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5566 da=_fam_cells->findIdsEqualList(0,0);
5568 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5573 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5578 if((const DataArrayInt *)_fam_faces)
5580 MCAuto<DataArrayInt> da;
5582 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5584 da=_fam_faces->findIdsEqualList(0,0);
5586 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5591 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5595 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5597 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5601 * Sets the family field of a given relative dimension.
5602 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5603 * the family field is set.
5604 * \param [in] famArr - the array of the family field.
5605 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5606 * \throw If \a famArr has an invalid size.
5607 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5609 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5611 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5613 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5614 switch(meshDimRelToMaxExt)
5618 int nbCells(mesh->getNumberOfCells());
5620 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5626 int nbNodes(mesh->getNumberOfNodes());
5628 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5634 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5636 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5641 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5648 * Sets the optional numbers of mesh entities of a given dimension.
5649 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5650 * \param [in] renumArr - the array of the numbers.
5651 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5652 * \throw If \a renumArr has an invalid size.
5653 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5655 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5657 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5659 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5660 switch(meshDimRelToMaxExt)
5664 int nbCells=mesh->getNumberOfCells();
5665 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5666 _num_cells=renumArr;
5671 int nbNodes=mesh->getNumberOfNodes();
5672 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5673 _num_nodes=renumArr;
5678 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5679 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5680 _num_faces=renumArr;
5684 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5687 renumArr->incrRef();
5691 * Sets the optional names of mesh entities of a given dimension.
5692 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5693 * \param [in] nameArr - the array of the names.
5694 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5695 * \throw If \a nameArr has an invalid size.
5697 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5699 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5701 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5702 switch(meshDimRelToMaxExt)
5706 int nbCells=mesh->getNumberOfCells();
5707 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5708 _names_cells=nameArr;
5713 int nbNodes=mesh->getNumberOfNodes();
5714 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5715 _names_nodes=nameArr;
5720 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5721 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5722 _names_cells=nameArr;
5725 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5732 * Adds a group of nodes to \a this mesh.
5733 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5734 * The ids should be sorted and different each other (MED file norm).
5736 * \warning this method can alter default "FAMILLE_ZERO" family.
5737 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5739 * \throw If the node coordinates array is not set.
5740 * \throw If \a ids == \c NULL.
5741 * \throw If \a ids->getName() == "".
5742 * \throw If \a ids does not respect the MED file norm.
5743 * \throw If a group with name \a ids->getName() already exists.
5745 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5751 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5753 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5754 * The ids should be sorted and different each other (MED file norm).
5756 * \warning this method can alter default "FAMILLE_ZERO" family.
5757 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5759 * \throw If the node coordinates array is not set.
5760 * \throw If \a ids == \c NULL.
5761 * \throw If \a ids->getName() == "".
5762 * \throw If \a ids does not respect the MED file norm.
5763 * \throw If a group with name \a ids->getName() already exists.
5765 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5767 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5768 addGroupUnderground(false,ids,fam);
5773 * Returns the family field for mesh entities of a given dimension.
5774 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5775 * \return const DataArrayInt * - the family field. It is an array of ids of families
5776 * each mesh entity belongs to. It can be \c NULL.
5777 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5779 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5781 switch(meshDimRelToMaxExt)
5790 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5795 * Returns the family field for mesh entities of a given dimension.
5796 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5797 * \return const DataArrayInt * - the family field. It is an array of ids of families
5798 * each mesh entity belongs to. It can be \c NULL.
5799 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5801 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5803 switch(meshDimRelToMaxExt)
5812 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5817 * Returns the optional numbers of mesh entities of a given dimension.
5818 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5819 * \return const DataArrayInt * - the array of the entity numbers.
5820 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5821 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5823 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5825 switch(meshDimRelToMaxExt)
5834 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5839 * Returns the optional numbers of mesh entities of a given dimension transformed using
5840 * DataArrayInt::invertArrayN2O2O2N().
5841 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5842 * \return const DataArrayInt * - the array of the entity numbers transformed using
5843 * DataArrayInt::invertArrayN2O2O2N().
5844 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5845 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5847 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5849 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5850 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5851 if(meshDimRelToMaxExt==0)
5853 if((const DataArrayInt *)_num_cells)
5856 int maxValue=_num_cells->getMaxValue(pos);
5857 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5858 return _rev_num_cells;
5861 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5865 if((const DataArrayInt *)_num_nodes)
5868 int maxValue=_num_nodes->getMaxValue(pos);
5869 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5870 return _rev_num_nodes;
5873 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5877 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5879 switch(meshDimRelToMaxExt)
5882 return _names_cells;
5884 return _names_nodes;
5886 return _names_faces;
5888 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5893 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5894 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5896 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5898 std::vector<int> ret(1);
5903 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5904 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5906 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5908 std::vector<int> ret(2);
5914 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5916 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5918 std::vector<int> ret;
5919 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5930 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5932 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5934 std::vector<int> ret;
5935 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5946 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5948 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5950 std::vector<int> ret;
5951 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5962 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5964 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5966 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5970 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5972 DataArrayInt *arr=_fam_nodes;
5974 arr->changeValue(oldId,newId);
5977 arr->changeValue(oldId,newId);
5980 arr->changeValue(oldId,newId);
5983 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5985 std::list< MCAuto<DataArrayInt> > ret;
5986 const DataArrayInt *da(_fam_nodes);
5988 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5991 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5994 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5998 void MEDFileStructuredMesh::deepCpyAttributes()
6000 if((const DataArrayInt*)_fam_nodes)
6001 _fam_nodes=_fam_nodes->deepCopy();
6002 if((const DataArrayInt*)_num_nodes)
6003 _num_nodes=_num_nodes->deepCopy();
6004 if((const DataArrayAsciiChar*)_names_nodes)
6005 _names_nodes=_names_nodes->deepCopy();
6006 if((const DataArrayInt*)_fam_cells)
6007 _fam_cells=_fam_cells->deepCopy();
6008 if((const DataArrayInt*)_num_cells)
6009 _num_cells=_num_cells->deepCopy();
6010 if((const DataArrayAsciiChar*)_names_cells)
6011 _names_cells=_names_cells->deepCopy();
6012 if((const DataArrayInt*)_fam_faces)
6013 _fam_faces=_fam_faces->deepCopy();
6014 if((const DataArrayInt*)_num_faces)
6015 _num_faces=_num_faces->deepCopy();
6016 if((const DataArrayAsciiChar*)_names_faces)
6017 _names_faces=_names_faces->deepCopy();
6018 if((const DataArrayInt*)_rev_num_nodes)
6019 _rev_num_nodes=_rev_num_nodes->deepCopy();
6020 if((const DataArrayInt*)_rev_num_cells)
6021 _rev_num_cells=_rev_num_cells->deepCopy();
6025 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
6027 * \return a pointer to cartesian mesh that need to be managed by the caller.
6028 * \warning the returned pointer has to be managed by the caller.
6032 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6033 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6034 * \param [in] renum - it must be \c false.
6035 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6036 * delete using decrRef() as it is no more needed.
6038 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6042 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6043 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6044 switch(meshDimRelToMax)
6050 return const_cast<MEDCouplingStructuredMesh *>(m);
6055 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6056 buildMinusOneImplicitPartIfNeeded();
6057 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6063 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6067 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6069 std::vector<int> ret;
6070 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6071 if(famCells && famCells->presenceOfValue(ret))
6073 if(famFaces && famFaces->presenceOfValue(ret))
6078 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6080 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6081 const DataArrayInt *famNodes(_fam_nodes);
6082 if(famNodes && famNodes->presenceOfValue(ret))
6088 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6089 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6090 * \return int - the number of entities.
6091 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6093 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6095 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6097 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6098 switch(meshDimRelToMaxExt)
6101 return cmesh->getNumberOfCells();
6103 return cmesh->getNumberOfNodes();
6105 return cmesh->getNumberOfCellsOfSubLevelMesh();
6107 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6111 int MEDFileStructuredMesh::getNumberOfNodes() const
6113 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6115 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6116 return cmesh->getNumberOfNodes();
6119 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6121 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6123 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6124 switch(meshDimRelToMaxExt)
6127 return cmesh->getNumberOfCells();
6129 return cmesh->getNumberOfCellsOfSubLevelMesh();
6131 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6135 bool MEDFileStructuredMesh::hasImplicitPart() const
6141 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6143 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6145 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6146 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6149 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6150 if(cm.getReverseExtrudedType()!=gt)
6151 throw INTERP_KERNEL::Exception(MSG);
6152 buildImplicitPart();
6153 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6157 if(gt!=zeFaceMesh->getCellModelEnum())
6158 throw INTERP_KERNEL::Exception(MSG);
6159 return zeFaceMesh->getNumberOfCells();
6163 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6165 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6167 buildImplicitPart();
6170 void MEDFileStructuredMesh::buildImplicitPart() const
6172 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6174 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6175 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6178 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6180 _faces_if_necessary=0;
6184 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6185 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6187 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6189 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6192 return _faces_if_necessary;
6195 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6197 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6199 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6200 switch(meshDimRelToMax)
6204 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6209 int mdim(cmesh->getMeshDimension());
6211 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6212 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6216 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6220 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6222 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6225 return getNumberOfCellsAtLevel(0);
6228 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6230 if(st.getNumberOfItems()!=1)
6231 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 !");
6232 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6233 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6234 if(getNumberOfNodes()!=(int)nodesFetched.size())
6235 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6236 if(st[0].getPflName().empty())
6238 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6241 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6242 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6243 int sz(nodesFetched.size());
6244 for(const int *work=arr->begin();work!=arr->end();work++)
6246 std::vector<int> conn;
6247 cmesh->getNodeIdsOfCell(*work,conn);
6248 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6249 if(*it>=0 && *it<sz)
6250 nodesFetched[*it]=true;
6252 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6256 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6258 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6262 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6263 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6265 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6266 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6268 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6271 if(!mrs || mrs->isCellFamilyFieldReading())
6273 famCells=DataArrayInt::New();
6274 famCells->alloc(nbOfElt,1);
6275 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6278 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6281 if(!mrs || mrs->isCellNumFieldReading())
6283 numCells=DataArrayInt::New();
6284 numCells->alloc(nbOfElt,1);
6285 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6288 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6291 if(!mrs || mrs->isCellNameFieldReading())
6293 namesCells=DataArrayAsciiChar::New();
6294 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6295 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6296 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6301 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6303 setName(strm->getName());
6304 setDescription(strm->getDescription());
6305 setUnivName(strm->getUnivName());
6306 setIteration(strm->getIteration());
6307 setOrder(strm->getOrder());
6308 setTimeValue(strm->getTime());
6309 setTimeUnit(strm->getTimeUnit());
6310 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6311 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6312 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6315 if(!mrs || mrs->isNodeFamilyFieldReading())
6317 int nbNodes(getNumberOfNodes());
6319 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6320 _fam_nodes=DataArrayInt::New();
6321 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6322 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...
6323 _fam_nodes->fillWithZero();
6324 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6327 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6330 if(!mrs || mrs->isNodeNumFieldReading())
6332 _num_nodes=DataArrayInt::New();
6333 _num_nodes->alloc(nbOfElt,1);
6334 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6337 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6340 if(!mrs || mrs->isNodeNameFieldReading())
6342 _names_nodes=DataArrayAsciiChar::New();
6343 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6344 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6345 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6348 int meshDim(getStructuredMesh()->getMeshDimension());
6349 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6351 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6354 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6356 int meshDim(getStructuredMesh()->getMeshDimension());
6357 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6359 if((const DataArrayInt *)_fam_cells)
6360 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6361 if((const DataArrayInt *)_fam_faces)
6362 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6363 if((const DataArrayInt *)_fam_nodes)
6364 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6365 if((const DataArrayInt *)_num_cells)
6366 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6367 if((const DataArrayInt *)_num_faces)
6368 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6369 if((const DataArrayInt *)_num_nodes)
6370 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6371 if((const DataArrayAsciiChar *)_names_cells)
6373 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6375 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6376 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6377 throw INTERP_KERNEL::Exception(oss.str().c_str());
6379 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6381 if((const DataArrayAsciiChar *)_names_faces)
6383 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6385 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6386 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6387 throw INTERP_KERNEL::Exception(oss.str().c_str());
6389 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6391 if((const DataArrayAsciiChar *)_names_nodes)
6393 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6395 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6396 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6397 throw INTERP_KERNEL::Exception(oss.str().c_str());
6399 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6402 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6406 * Returns an empty instance of MEDFileCMesh.
6407 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6408 * mesh using decrRef() as it is no more needed.
6410 MEDFileCMesh *MEDFileCMesh::New()
6412 return new MEDFileCMesh;
6416 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6417 * file. The first mesh in the file is loaded.
6418 * \param [in] fileName - the name of MED file to read.
6419 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6420 * mesh using decrRef() as it is no more needed.
6421 * \throw If the file is not readable.
6422 * \throw If there is no meshes in the file.
6423 * \throw If the mesh in the file is not a Cartesian one.
6425 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6427 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6428 return New(fid,mrs);
6431 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6433 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6437 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6438 * file. The mesh to load is specified by its name and numbers of a time step and an
6440 * \param [in] fileName - the name of MED file to read.
6441 * \param [in] mName - the name of the mesh to read.
6442 * \param [in] dt - the number of a time step.
6443 * \param [in] it - the number of an iteration.
6444 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6445 * mesh using decrRef() as it is no more needed.
6446 * \throw If the file is not readable.
6447 * \throw If there is no mesh with given attributes in the file.
6448 * \throw If the mesh in the file is not a Cartesian one.
6450 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6452 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6453 return New(fid,mName,dt,it,mrs);
6456 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6458 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6461 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6463 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6466 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6468 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6469 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6474 * Returns the dimension on cells in \a this mesh.
6475 * \return int - the mesh dimension.
6476 * \throw If there are no cells in this mesh.
6478 int MEDFileCMesh::getMeshDimension() const
6480 if(!((const MEDCouplingCMesh*)_cmesh))
6481 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6482 return _cmesh->getMeshDimension();
6486 * Returns the dimension on nodes in \a this mesh.
6487 * \return int - the space dimension.
6488 * \throw If there are no cells in this mesh.
6490 int MEDFileCMesh::getSpaceDimension() const
6492 if(!((const MEDCouplingCMesh*)_cmesh))
6493 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6494 return _cmesh->getSpaceDimension();
6498 * Returns a string describing \a this mesh.
6499 * \return std::string - the mesh information string.
6501 std::string MEDFileCMesh::simpleRepr() const
6503 return MEDFileStructuredMesh::simpleRepr();
6507 * Returns a full textual description of \a this mesh.
6508 * \return std::string - the string holding the mesh description.
6510 std::string MEDFileCMesh::advancedRepr() const
6512 return simpleRepr();
6515 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6517 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6521 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6523 return new MEDFileCMesh;
6526 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6528 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6529 ret->deepCpyEquivalences(*this);
6530 if((const MEDCouplingCMesh*)_cmesh)
6531 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6532 ret->deepCpyAttributes();
6537 * Checks if \a this and another mesh are equal.
6538 * \param [in] other - the mesh to compare with.
6539 * \param [in] eps - a precision used to compare real values.
6540 * \param [in,out] what - the string returning description of unequal data.
6541 * \return bool - \c true if the meshes are equal, \c false, else.
6543 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6545 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6547 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6550 what="Mesh types differ ! This is cartesian and other is NOT !";
6553 clearNonDiscrAttributes();
6554 otherC->clearNonDiscrAttributes();
6555 const MEDCouplingCMesh *coo1=_cmesh;
6556 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6557 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6559 what="Mismatch of cartesian meshes ! One is defined and not other !";
6564 bool ret=coo1->isEqual(coo2,eps);
6567 what="cartesian meshes differ !";
6575 * Clears redundant attributes of incorporated data arrays.
6577 void MEDFileCMesh::clearNonDiscrAttributes() const
6579 MEDFileStructuredMesh::clearNonDiscrAttributes();
6580 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6583 MEDFileCMesh::MEDFileCMesh()
6587 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6590 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6592 catch(INTERP_KERNEL::Exception& e)
6597 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6599 MEDCoupling::MEDCouplingMeshType meshType;
6602 MEDCoupling::MEDCouplingAxisType axType;
6603 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6604 if(meshType!=CARTESIAN)
6606 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6607 throw INTERP_KERNEL::Exception(oss.str().c_str());
6609 MEDFileCMeshL2 loaderl2;
6610 loaderl2.loadAll(fid,mid,mName,dt,it);
6611 setAxisType(axType);
6612 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6615 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6619 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6620 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6622 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6624 synchronizeTinyInfoOnLeaves();
6628 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6630 synchronizeTinyInfoOnLeaves();
6635 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6636 * \param [in] m - the new MEDCouplingCMesh to refer to.
6637 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6640 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6642 dealWithTinyInfo(m);
6648 MEDFileMesh *MEDFileCMesh::cartesianize() const
6650 if(getAxisType()==AX_CART)
6653 return const_cast<MEDFileCMesh *>(this);
6657 const MEDCouplingCMesh *cmesh(getMesh());
6659 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6660 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6661 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6662 clmesh->setCoords(coords);
6663 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6664 ret->MEDFileStructuredMesh::operator=(*this);
6665 ret->setMesh(clmesh);
6666 ret->setAxisType(AX_CART);
6671 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6673 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6674 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6675 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6676 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6677 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6678 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6679 int spaceDim(_cmesh->getSpaceDimension());
6680 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6681 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6682 for(int i=0;i<spaceDim;i++)
6684 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6686 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6687 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
6688 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
6690 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6692 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6693 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6694 for(int i=0;i<spaceDim;i++)
6696 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6697 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6700 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6701 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6704 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6706 const MEDCouplingCMesh *cmesh=_cmesh;
6709 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6710 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6711 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6712 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6715 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6717 return new MEDFileCurveLinearMesh;
6720 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6722 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6725 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6727 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6728 return New(fid,mrs);
6731 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6733 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6734 return New(fid,mName,dt,it,mrs);
6737 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6739 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6742 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6744 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6747 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6749 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6750 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6754 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6756 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6760 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6762 return new MEDFileCurveLinearMesh;
6765 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6767 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6768 ret->deepCpyEquivalences(*this);
6769 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6770 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6771 ret->deepCpyAttributes();
6775 int MEDFileCurveLinearMesh::getMeshDimension() const
6777 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6778 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6779 return _clmesh->getMeshDimension();
6782 std::string MEDFileCurveLinearMesh::simpleRepr() const
6784 return MEDFileStructuredMesh::simpleRepr();
6787 std::string MEDFileCurveLinearMesh::advancedRepr() const
6789 return simpleRepr();
6792 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6794 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6796 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6799 what="Mesh types differ ! This is curve linear and other is NOT !";
6802 clearNonDiscrAttributes();
6803 otherC->clearNonDiscrAttributes();
6804 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6805 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6806 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6808 what="Mismatch of curve linear meshes ! One is defined and not other !";
6813 bool ret=coo1->isEqual(coo2,eps);
6816 what="curve linear meshes differ !";
6823 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6825 MEDFileStructuredMesh::clearNonDiscrAttributes();
6826 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6829 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6831 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6834 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6835 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6836 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6837 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6840 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6842 synchronizeTinyInfoOnLeaves();
6846 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6848 dealWithTinyInfo(m);
6854 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6856 if(getAxisType()==AX_CART)
6859 return const_cast<MEDFileCurveLinearMesh *>(this);
6863 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6865 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6866 const DataArrayDouble *coords(mesh->getCoords());
6868 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6869 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6870 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6871 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6872 mesh2->setCoords(coordsCart);
6873 ret->setMesh(mesh2);
6874 ret->setAxisType(AX_CART);
6879 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6881 synchronizeTinyInfoOnLeaves();
6885 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6889 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6892 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6894 catch(INTERP_KERNEL::Exception& e)
6899 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
6901 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6902 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6903 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6904 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6905 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6906 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6907 int spaceDim=_clmesh->getSpaceDimension();
6908 int meshDim=_clmesh->getMeshDimension();
6909 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6910 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6911 const DataArrayDouble *coords=_clmesh->getCoords();
6913 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
6914 for(int i=0;i<spaceDim;i++)
6916 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6918 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6919 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
6920 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
6922 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6924 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6925 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6926 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6927 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6929 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6931 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6932 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6935 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6937 MEDCoupling::MEDCouplingMeshType meshType;
6940 MEDCoupling::MEDCouplingAxisType axType;
6941 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
6942 setAxisType(axType);
6943 if(meshType!=CURVE_LINEAR)
6945 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6946 throw INTERP_KERNEL::Exception(oss.str().c_str());
6948 MEDFileCLMeshL2 loaderl2;
6949 loaderl2.loadAll(fid,mid,mName,dt,it);
6950 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6953 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6956 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6958 return new MEDFileMeshMultiTS;
6961 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
6963 return new MEDFileMeshMultiTS(fid);
6966 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6968 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6972 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
6974 return new MEDFileMeshMultiTS(fid,mName);
6977 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6979 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6980 return New(fid,mName);
6983 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
6985 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
6986 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6988 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6989 if((const MEDFileMesh *)*it)
6990 meshOneTs[i]=(*it)->deepCopy();
6991 ret->_mesh_one_ts=meshOneTs;
6995 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6997 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
7000 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7002 std::vector<const BigMemoryObject *> ret;
7003 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7004 ret.push_back((const MEDFileMesh *)*it);
7008 std::string MEDFileMeshMultiTS::getName() const
7010 if(_mesh_one_ts.empty())
7011 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7012 return _mesh_one_ts[0]->getName();
7015 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7017 std::string oldName(getName());
7018 std::vector< std::pair<std::string,std::string> > v(1);
7019 v[0].first=oldName; v[0].second=newMeshName;
7023 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7026 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7028 MEDFileMesh *cur(*it);
7030 ret=cur->changeNames(modifTab) || ret;
7035 void MEDFileMeshMultiTS::cartesianizeMe()
7037 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7039 MEDFileMesh *cur(*it);
7042 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7048 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7050 if(_mesh_one_ts.empty())
7051 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7052 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7055 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7058 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7059 _mesh_one_ts.resize(1);
7060 mesh1TimeStep->incrRef();
7061 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7062 _mesh_one_ts[0]=mesh1TimeStep;
7065 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7067 if ( MEDFileMesh* m = getOneTimeStep() )
7068 return m->getJoints();
7073 * \brief Set Joints that are common to all time-stamps
7075 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7077 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7079 (*it)->setJoints( joints );
7083 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7085 MEDFileJoints *joints(getJoints());
7086 bool jointsWritten(false);
7088 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7090 if ( jointsWritten )
7091 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7093 jointsWritten = true;
7095 (*it)->copyOptionsFrom(*this);
7096 (*it)->writeLL(fid);
7099 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7102 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7104 MEDFileJoints *joints(0);
7105 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7107 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7108 joints = getOneTimeStep()->getJoints();
7110 _mesh_one_ts.clear(); //for the moment to be improved
7111 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7114 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7118 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7121 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7124 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7125 throw INTERP_KERNEL::Exception(oss.str().c_str());
7128 MEDCoupling::MEDCouplingMeshType meshType;
7130 MEDCoupling::MEDCouplingAxisType dummy3;
7131 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7132 loadFromFile(fid,ms.front());
7134 catch(INTERP_KERNEL::Exception& e)
7139 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7142 loadFromFile(fid,mName);
7144 catch(INTERP_KERNEL::Exception& e)
7149 MEDFileMeshes *MEDFileMeshes::New()
7151 return new MEDFileMeshes;
7154 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7156 return new MEDFileMeshes(fid);
7159 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7161 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7165 void MEDFileMeshes::writeLL(med_idt fid) const
7167 checkConsistencyLight();
7168 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7170 (*it)->copyOptionsFrom(*this);
7171 (*it)->writeLL(fid);
7175 // MEDFileMeshes::writ checkConsistencyLight();
7177 int MEDFileMeshes::getNumberOfMeshes() const
7179 return _meshes.size();
7182 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7184 return new MEDFileMeshesIterator(this);
7187 /** Return a borrowed reference (caller is not responsible) */
7188 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7190 if(i<0 || i>=(int)_meshes.size())
7192 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7193 throw INTERP_KERNEL::Exception(oss.str().c_str());
7195 return _meshes[i]->getOneTimeStep();
7198 /** Return a borrowed reference (caller is not responsible) */
7199 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7201 std::vector<std::string> ms=getMeshesNames();
7202 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7205 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7206 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7207 throw INTERP_KERNEL::Exception(oss.str().c_str());
7209 return getMeshAtPos((int)std::distance(ms.begin(),it));
7212 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7214 std::vector<std::string> ret(_meshes.size());
7216 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7218 const MEDFileMeshMultiTS *f=(*it);
7221 ret[i]=f->getName();
7225 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7226 throw INTERP_KERNEL::Exception(oss.str().c_str());
7232 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7235 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7237 MEDFileMeshMultiTS *cur(*it);
7239 ret=cur->changeNames(modifTab) || ret;
7244 void MEDFileMeshes::cartesianizeMe()
7246 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7248 MEDFileMeshMultiTS *cur(*it);
7250 cur->cartesianizeMe();
7254 void MEDFileMeshes::resize(int newSize)
7256 _meshes.resize(newSize);
7259 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7262 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7263 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7264 elt->setOneTimeStep(mesh);
7265 _meshes.push_back(elt);
7268 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7271 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7272 if(i>=(int)_meshes.size())
7273 _meshes.resize(i+1);
7274 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7275 elt->setOneTimeStep(mesh);
7279 void MEDFileMeshes::destroyMeshAtPos(int i)
7281 if(i<0 || i>=(int)_meshes.size())
7283 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7284 throw INTERP_KERNEL::Exception(oss.str().c_str());
7286 _meshes.erase(_meshes.begin()+i);
7289 void MEDFileMeshes::loadFromFile(med_idt fid)
7291 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7293 _meshes.resize(ms.size());
7294 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7295 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7298 MEDFileMeshes::MEDFileMeshes()
7302 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7307 catch(INTERP_KERNEL::Exception& /*e*/)
7311 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7313 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7315 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7316 if((const MEDFileMeshMultiTS *)*it)
7317 meshes[i]=(*it)->deepCopy();
7318 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7319 ret->_meshes=meshes;
7323 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7325 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7328 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7330 std::vector<const BigMemoryObject *> ret;
7331 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7332 ret.push_back((const MEDFileMeshMultiTS *)*it);
7336 std::string MEDFileMeshes::simpleRepr() const
7338 std::ostringstream oss;
7339 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7340 simpleReprWithoutHeader(oss);
7344 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7346 int nbOfMeshes=getNumberOfMeshes();
7347 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7348 std::vector<std::string> mns=getMeshesNames();
7349 for(int i=0;i<nbOfMeshes;i++)
7350 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7353 void MEDFileMeshes::checkConsistencyLight() const
7355 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7357 std::set<std::string> s;
7358 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7360 const MEDFileMeshMultiTS *elt=(*it);
7363 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7364 throw INTERP_KERNEL::Exception(oss.str().c_str());
7366 std::size_t sz=s.size();
7367 s.insert(std::string((*it)->getName()));
7370 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7371 throw INTERP_KERNEL::Exception(oss.str().c_str());
7376 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7381 _nb_iter=ms->getNumberOfMeshes();
7385 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7389 MEDFileMesh *MEDFileMeshesIterator::nextt()
7391 if(_iter_id<_nb_iter)
7393 MEDFileMeshes *ms(_ms);
7395 return ms->getMeshAtPos(_iter_id++);
7403 INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
7405 med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
7406 if(pos==typmai+MED_N_CELL_FIXED_GEO)
7408 if(geoType==MED_NO_GEOTYPE)
7409 return INTERP_KERNEL::NORM_ERROR;
7410 std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !";
7411 throw INTERP_KERNEL::Exception(oss.str());
7413 return typmai2[std::distance(typmai,pos)];
7416 TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
7426 std::ostringstream oss; oss << "EDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
7427 throw INTERP_KERNEL::Exception(oss.str());