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 "MEDFileUtilities.hxx"
23 #include "MEDFileFieldOverView.hxx"
24 #include "MEDFileField.hxx"
25 #include "MEDLoader.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 typmai3[34];
39 using namespace MEDCoupling;
41 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
43 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
45 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
49 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
51 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
52 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
54 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
55 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
56 ret+=(*it2).capacity();
58 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
59 ret+=(*it).first.capacity()+sizeof(int);
63 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
65 std::vector<const BigMemoryObject *> ret(1);
66 ret[0]=(const MEDFileEquivalences *)_equiv;
71 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
72 * file. The first mesh in the file is loaded.
73 * \param [in] fileName - the name of MED file to read.
74 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
75 * mesh using decrRef() as it is no more needed.
76 * \throw If the file is not readable.
77 * \throw If there is no meshes in the file.
78 * \throw If the mesh in the file is of a not supported type.
80 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
82 std::vector<std::string> ms=MEDCoupling::GetMeshNames(fileName);
85 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
86 throw INTERP_KERNEL::Exception(oss.str().c_str());
88 MEDFileUtilities::CheckFileForRead(fileName);
89 MEDCoupling::MEDCouplingMeshType meshType;
90 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
93 MEDCoupling::MEDCouplingAxisType dummy3;
94 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
95 MCAuto<MEDFileMesh> ret;
100 ret=MEDFileUMesh::New();
105 ret=MEDFileCMesh::New();
110 ret=MEDFileCurveLinearMesh::New();
115 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
116 throw INTERP_KERNEL::Exception(oss.str().c_str());
119 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
124 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
125 * file. The mesh to load is specified by its name and numbers of a time step and an
127 * \param [in] fileName - the name of MED file to read.
128 * \param [in] mName - the name of the mesh to read.
129 * \param [in] dt - the number of a time step.
130 * \param [in] it - the number of an iteration.
131 * \param [in] joints - the sub-domain joints to use instead of those that can be read
132 * from the MED file. Usually this joints are those just read by another iteration
133 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
134 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
135 * mesh using decrRef() as it is no more needed.
136 * \throw If the file is not readable.
137 * \throw If there is no mesh with given attributes in the file.
138 * \throw If the mesh in the file is of a not supported type.
140 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
142 MEDFileUtilities::CheckFileForRead(fileName);
143 MEDCoupling::MEDCouplingMeshType meshType;
144 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
147 MEDCoupling::MEDCouplingAxisType dummy3;
148 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
149 MCAuto<MEDFileMesh> ret;
154 ret=MEDFileUMesh::New();
159 ret=MEDFileCMesh::New();
164 ret=MEDFileCurveLinearMesh::New();
169 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
170 throw INTERP_KERNEL::Exception(oss.str().c_str());
173 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
178 * Writes \a this mesh into an open MED file specified by its descriptor.
179 * \param [in] fid - the MED file descriptor.
180 * \throw If the mesh name is not set.
181 * \throw If the file is open for reading only.
182 * \throw If the writing mode == 1 and the same data is present in an existing file.
184 void MEDFileMesh::writeLL(med_idt fid) const
187 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
189 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
192 const MEDFileEquivalences *eqs(_equiv);
198 * Checks if \a this and another mesh are equal.
199 * \param [in] other - the mesh to compare with.
200 * \param [in] eps - a precision used to compare real values.
201 * \param [in,out] what - the string returning description of unequal data.
202 * \return bool - \c true if the meshes are equal, \c false, else.
204 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
206 if(_order!=other->_order)
208 what="Orders differ !";
211 if(_iteration!=other->_iteration)
213 what="Iterations differ !";
216 if(fabs(_time-other->_time)>eps)
218 what="Time values differ !";
221 if(_dt_unit!=other->_dt_unit)
223 what="Time units differ !";
226 if(_name!=other->_name)
228 what="Names differ !";
231 //univ_name has been ignored -> not a bug because it is a mutable attribute
232 if(_desc_name!=other->_desc_name)
234 what="Description names differ !";
237 if(!areGrpsEqual(other,what))
239 if(!areFamsEqual(other,what))
241 if(!areEquivalencesEqual(other,what))
246 void MEDFileMesh::setName(const std::string& name)
252 * Clears redundant attributes of incorporated data arrays.
254 void MEDFileMesh::clearNonDiscrAttributes() const
259 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
261 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
263 if((*it).first==_name)
273 * Copies data on groups and families from another mesh.
274 * \param [in] other - the mesh to copy the data from.
276 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
278 _groups=other._groups;
279 _families=other._families;
284 * This method clear all the groups in the map.
285 * So this method does not operate at all on arrays.
286 * So this method can lead to orphan families.
288 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
290 void MEDFileMesh::clearGrpMap()
296 * This method clear all the families in the map.
297 * So this method does not operate at all on arrays.
298 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
300 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
302 void MEDFileMesh::clearFamMap()
308 * This method clear all the families and groups in the map.
309 * So this method does not operate at all on arrays.
310 * As all groups and families entry will be removed after
311 * 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.
313 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
315 void MEDFileMesh::clearFamGrpMaps()
322 * Returns names of families constituting a group.
323 * \param [in] name - the name of the group of interest.
324 * \return std::vector<std::string> - a sequence of names of the families.
325 * \throw If the name of a nonexistent group is specified.
327 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
329 std::string oname(name);
330 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
331 if(it==_groups.end())
333 std::vector<std::string> grps=getGroupsNames();
334 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
335 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
336 throw INTERP_KERNEL::Exception(oss.str().c_str());
342 * Returns names of families constituting some groups.
343 * \param [in] grps - a sequence of names of groups of interest.
344 * \return std::vector<std::string> - a sequence of names of the families.
345 * \throw If a name of a nonexistent group is present in \a grps.
347 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
349 std::set<std::string> fams;
350 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
352 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
353 if(it2==_groups.end())
355 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
356 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
357 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
358 throw INTERP_KERNEL::Exception(oss.str().c_str());
360 fams.insert((*it2).second.begin(),(*it2).second.end());
362 std::vector<std::string> fams2(fams.begin(),fams.end());
367 * Returns ids of families constituting a group.
368 * \param [in] name - the name of the group of interest.
369 * \return std::vector<int> - sequence of ids of the families.
370 * \throw If the name of a nonexistent group is specified.
372 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
374 std::string oname(name);
375 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
376 std::vector<std::string> grps=getGroupsNames();
377 if(it==_groups.end())
379 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
380 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
381 throw INTERP_KERNEL::Exception(oss.str().c_str());
383 return getFamiliesIds((*it).second);
387 * Sets names of families constituting a group. If data on families of this group is
388 * already present, it is overwritten. Every family in \a fams is checked, and if a
389 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
390 * \param [in] name - the name of the group of interest.
391 * \param [in] fams - a sequence of names of families constituting the group.
393 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
395 std::string oname(name);
397 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
399 std::map<std::string,int>::iterator it2=_families.find(*it1);
400 if(it2==_families.end())
406 * Sets families constituting a group. The families are specified by their ids.
407 * If a family name is not found by its id, an exception is thrown.
408 * If several families have same id, the first one in lexical order is taken.
409 * \param [in] name - the name of the group of interest.
410 * \param [in] famIds - a sequence of ids of families constituting the group.
411 * \throw If a family name is not found by its id.
413 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
415 std::string oname(name);
416 std::vector<std::string> fams(famIds.size());
418 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
420 std::string name2=getFamilyNameGivenId(*it1);
427 * Returns names of groups including a given family.
428 * \param [in] name - the name of the family of interest.
429 * \return std::vector<std::string> - a sequence of names of groups including the family.
431 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
433 std::vector<std::string> ret;
434 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
436 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
439 ret.push_back((*it1).first);
447 * Adds an existing family to groups.
448 * \param [in] famName - a name of family to add to \a grps.
449 * \param [in] grps - a sequence of group names to add the family in.
450 * \throw If a family named \a famName not yet exists.
452 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
454 std::string fName(famName);
455 const std::map<std::string,int>::const_iterator it=_families.find(fName);
456 if(it==_families.end())
458 std::vector<std::string> fams=getFamiliesNames();
459 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
460 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
461 throw INTERP_KERNEL::Exception(oss.str().c_str());
463 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
465 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
466 if(it2!=_groups.end())
467 (*it2).second.push_back(fName);
470 std::vector<std::string> grps2(1,fName);
477 * Returns names of all groups of \a this mesh.
478 * \return std::vector<std::string> - a sequence of group names.
480 std::vector<std::string> MEDFileMesh::getGroupsNames() const
482 std::vector<std::string> ret(_groups.size());
484 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
490 * Returns names of all families of \a this mesh.
491 * \return std::vector<std::string> - a sequence of family names.
493 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
495 std::vector<std::string> ret(_families.size());
497 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
503 * Returns names of all families of \a this mesh but like they would be in file.
504 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
505 * 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 !
506 * For your information internaly in memory such families are renamed to have a nicer API.
508 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
510 std::vector<std::string> ret(getFamiliesNames());
511 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
516 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
517 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
518 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
521 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
523 std::vector<std::string> ret;
524 std::vector<std::string> allGrps(getGroupsNames());
525 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
527 std::vector<int> levs(getGrpNonEmptyLevelsExt((*it)));
528 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
535 * Returns all relative mesh levels (including nodes) where a given group is defined.
536 * \param [in] grp - the name of the group of interest.
537 * \return std::vector<int> - a sequence of the relative dimensions.
539 std::vector<int> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
541 std::vector<std::string> fams(getFamiliesOnGroup(grp));
542 return getFamsNonEmptyLevelsExt(fams);
546 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
547 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
548 * \param [in] grps - a sequence of names of the groups of interest.
549 * \return std::vector<int> - a sequence of the relative dimensions.
551 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
553 std::vector<std::string> fams(getFamiliesOnGroups(grps));
554 return getFamsNonEmptyLevels(fams);
558 * Returns all relative mesh levels (including nodes) where given groups are defined.
559 * \param [in] grps - a sequence of names of the groups of interest.
560 * \return std::vector<int> - a sequence of the relative dimensions.
562 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
564 std::vector<std::string> fams(getFamiliesOnGroups(grps));
565 return getFamsNonEmptyLevelsExt(fams);
569 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
570 * To include nodes, call getGrpNonEmptyLevelsExt() method.
571 * \param [in] grp - the name of the group of interest.
572 * \return std::vector<int> - a sequence of the relative dimensions.
574 std::vector<int> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
576 std::vector<std::string> fams(getFamiliesOnGroup(grp));
577 return getFamsNonEmptyLevels(fams);
581 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
582 * To include nodes, call getFamNonEmptyLevelsExt() method.
583 * \param [in] fam - the name of the family of interest.
584 * \return std::vector<int> - a sequence of the relative dimensions.
586 std::vector<int> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
588 std::vector<std::string> fams(1,std::string(fam));
589 return getFamsNonEmptyLevels(fams);
593 * Returns all relative mesh levels (including nodes) where a given family is defined.
594 * \param [in] fam - the name of the family of interest.
595 * \return std::vector<int> - a sequence of the relative dimensions.
597 std::vector<int> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
599 std::vector<std::string> fams(1,std::string(fam));
600 return getFamsNonEmptyLevelsExt(fams);
603 std::string MEDFileMesh::GetMagicFamilyStr()
605 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
609 * Changes a name of every family, included in one group only, to be same as the group name.
610 * \throw If there are families with equal names in \a this mesh.
612 void MEDFileMesh::assignFamilyNameWithGroupName()
614 std::map<std::string, std::vector<std::string> > groups(_groups);
615 std::map<std::string,int> newFams;
616 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
618 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
619 if(grps.size()==1 && groups[grps[0]].size()==1)
621 if(newFams.find(grps[0])!=newFams.end())
623 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
624 throw INTERP_KERNEL::Exception(oss.str().c_str());
626 newFams[grps[0]]=(*it).second;
627 std::vector<std::string>& grps2=groups[grps[0]];
628 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
633 if(newFams.find((*it).first)!=newFams.end())
635 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
636 throw INTERP_KERNEL::Exception(oss.str().c_str());
638 newFams[(*it).first]=(*it).second;
646 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
648 * \return the removed groups.
650 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
652 std::vector<std::string> ret;
653 std::map<std::string, std::vector<std::string> > newGrps;
654 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
656 if((*it).second.empty())
657 ret.push_back((*it).first);
659 newGrps[(*it).first]=(*it).second;
667 * Removes a group from \a this mesh.
668 * \param [in] name - the name of the group to remove.
669 * \throw If no group with such a \a name exists.
671 void MEDFileMesh::removeGroup(const std::string& name)
673 std::string oname(name);
674 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
675 std::vector<std::string> grps=getGroupsNames();
676 if(it==_groups.end())
678 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
679 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
680 throw INTERP_KERNEL::Exception(oss.str().c_str());
686 * Removes a family from \a this mesh.
687 * \param [in] name - the name of the family to remove.
688 * \throw If no family with such a \a name exists.
690 void MEDFileMesh::removeFamily(const std::string& name)
692 std::string oname(name);
693 std::map<std::string, int >::iterator it=_families.find(oname);
694 std::vector<std::string> fams=getFamiliesNames();
695 if(it==_families.end())
697 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
698 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
699 throw INTERP_KERNEL::Exception(oss.str().c_str());
702 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
704 std::vector<std::string>& v=(*it3).second;
705 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
712 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
713 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
714 * family field whatever its level. This method also suppresses the orphan families.
716 * \return - The list of removed groups names.
718 * \sa MEDFileMesh::removeOrphanFamilies.
720 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
722 removeOrphanFamilies();
723 return removeEmptyGroups();
727 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
728 * 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.
730 * \return - The list of removed families names.
731 * \sa MEDFileMesh::removeOrphanGroups.
733 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
735 MCAuto<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
736 std::vector<std::string> ret;
737 if(!((DataArrayInt*)allFamIdsInUse))
739 ret=getFamiliesNames();
740 _families.clear(); _groups.clear();
743 std::map<std::string,int> famMap;
744 std::map<std::string, std::vector<std::string> > grps(_groups);
745 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
747 if(allFamIdsInUse->presenceOfValue((*it).second))
748 famMap[(*it).first]=(*it).second;
751 ret.push_back((*it).first);
752 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
753 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
755 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
756 std::vector<std::string>& famv=(*it3).second;
757 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
763 { _families=famMap; _groups=grps; }
768 * 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
769 * this family is orphan or not.
771 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
773 void MEDFileMesh::removeFamiliesReferedByNoGroups()
775 std::map<std::string,int> fams;
776 std::set<std::string> sfams;
777 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
778 sfams.insert((*it).first);
779 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
780 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
782 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
783 if(*it!=DFT_FAM_NAME)
784 _families.erase(*it);
788 * 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
789 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
790 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
792 * \sa MEDFileMesh::removeOrphanFamilies
794 void MEDFileMesh::rearrangeFamilies()
796 checkOrphanFamilyZero();
797 removeFamiliesReferedByNoGroups();
799 std::vector<int> levels(getNonEmptyLevelsExt());
800 std::set<int> idsRefed;
801 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
802 idsRefed.insert((*it).second);
803 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
805 const DataArrayInt *fams(0);
808 fams=getFamilyFieldAtLevel(*it);
810 catch(INTERP_KERNEL::Exception& e) { }
813 std::vector<bool> v(fams->getNumberOfTuples(),false);
814 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
815 fams->switchOnTupleEqualTo(*pt,v);
816 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
817 if(!unfetchedIds->empty())
819 MCAuto<DataArrayInt> newFams(fams->deepCopy());
820 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
821 setFamilyFieldArr(*it,newFams);
824 removeOrphanFamilies();
828 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
830 void MEDFileMesh::checkOrphanFamilyZero() const
832 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
834 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
836 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
837 throw INTERP_KERNEL::Exception(oss.str().c_str());
843 * Renames a group in \a this mesh.
844 * \param [in] oldName - a current name of the group to rename.
845 * \param [in] newName - a new group name.
846 * \throw If no group named \a oldName exists in \a this mesh.
847 * \throw If a group named \a newName already exists.
849 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
851 std::string oname(oldName);
852 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
853 std::vector<std::string> grps=getGroupsNames();
854 if(it==_groups.end())
856 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
857 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
858 throw INTERP_KERNEL::Exception(oss.str().c_str());
860 std::string nname(newName);
861 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
862 if(it2!=_groups.end())
864 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
865 throw INTERP_KERNEL::Exception(oss.str().c_str());
867 std::vector<std::string> cpy=(*it).second;
869 _groups[newName]=cpy;
873 * Changes an id of a family in \a this mesh.
874 * This method calls changeFamilyIdArr().
875 * \param [in] oldId - a current id of the family.
876 * \param [in] newId - a new family id.
878 void MEDFileMesh::changeFamilyId(int oldId, int newId)
880 changeFamilyIdArr(oldId,newId);
881 std::map<std::string,int> fam2;
882 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
884 if((*it).second==oldId)
885 fam2[(*it).first]=newId;
887 fam2[(*it).first]=(*it).second;
893 * Renames a family in \a this mesh.
894 * \param [in] oldName - a current name of the family to rename.
895 * \param [in] newName - a new family name.
896 * \throw If no family named \a oldName exists in \a this mesh.
897 * \throw If a family named \a newName already exists.
899 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
901 std::string oname(oldName);
902 std::map<std::string, int >::iterator it=_families.find(oname);
903 std::vector<std::string> fams=getFamiliesNames();
904 if(it==_families.end())
906 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
907 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
908 throw INTERP_KERNEL::Exception(oss.str().c_str());
910 std::string nname(newName);
911 std::map<std::string, int >::iterator it2=_families.find(nname);
912 if(it2!=_families.end())
914 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
915 throw INTERP_KERNEL::Exception(oss.str().c_str());
917 int cpy=(*it).second;
919 _families[newName]=cpy;
920 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
922 std::vector<std::string>& v=(*it3).second;
923 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
930 * Checks if \a this and another mesh contains the same families.
931 * \param [in] other - the mesh to compare with \a this one.
932 * \param [in,out] what - an unused parameter.
933 * \return bool - \c true if number of families and their ids are the same in the two
934 * meshes. Families with the id == \c 0 are not considered.
936 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
938 if(_families==other->_families)
940 std::map<std::string,int> fam0;
941 std::map<std::string,int> fam1;
942 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
944 fam0[(*it).first]=(*it).second;
945 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
947 fam1[(*it).first]=(*it).second;
952 * Checks if \a this and another mesh contains the same groups.
953 * \param [in] other - the mesh to compare with \a this one.
954 * \param [in,out] what - a string describing a difference of groups of the two meshes
955 * in case if this method returns \c false.
956 * \return bool - \c true if number of groups and families constituting them are the
957 * same in the two meshes.
959 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
961 if(_groups==other->_groups)
964 std::size_t sz=_groups.size();
965 if(sz!=other->_groups.size())
967 what="Groups differ because not same number !\n";
972 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
973 for(std::size_t i=0;i<sz && ret;i++,it1++)
975 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
976 if(it2!=other->_groups.end())
978 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
979 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
985 what="A group in first mesh exists not in other !\n";
991 std::ostringstream oss; oss << "Groups description differs :\n";
992 oss << "First group description :\n";
993 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
995 oss << " Group \"" << (*it).first << "\" on following families :\n";
996 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
997 oss << " \"" << *it2 << "\n";
999 oss << "Second group description :\n";
1000 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1002 oss << " Group \"" << (*it).first << "\" on following families :\n";
1003 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1004 oss << " \"" << *it2 << "\n";
1012 * Checks if a group with a given name exists in \a this mesh.
1013 * \param [in] groupName - the group name.
1014 * \return bool - \c true the group \a groupName exists in \a this mesh.
1016 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1018 std::string grpName(groupName);
1019 return _groups.find(grpName)!=_groups.end();
1023 * Checks if a family with a given id exists in \a this mesh.
1024 * \param [in] famId - the family id.
1025 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1027 bool MEDFileMesh::existsFamily(int famId) const
1029 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1030 if((*it2).second==famId)
1036 * Checks if a family with a given name exists in \a this mesh.
1037 * \param [in] familyName - the family name.
1038 * \return bool - \c true the family \a familyName exists in \a this mesh.
1040 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1042 std::string fname(familyName);
1043 return _families.find(fname)!=_families.end();
1047 * Sets an id of a family.
1048 * \param [in] familyName - the family name.
1049 * \param [in] id - a new id of the family.
1051 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1053 std::string fname(familyName);
1054 _families[fname]=id;
1057 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1059 std::string fname(familyName);
1060 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1061 if((*it).second==id)
1063 if((*it).first!=familyName)
1065 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1066 throw INTERP_KERNEL::Exception(oss.str().c_str());
1069 _families[fname]=id;
1073 * Adds a family to \a this mesh.
1074 * \param [in] familyName - a name of the family.
1075 * \param [in] famId - an id of the family.
1076 * \throw If a family with the same name or id already exists in \a this mesh.
1078 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1080 std::string fname(familyName);
1081 std::map<std::string,int>::const_iterator it=_families.find(fname);
1082 if(it==_families.end())
1084 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1085 if((*it2).second==famId)
1087 std::ostringstream oss;
1088 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1089 throw INTERP_KERNEL::Exception(oss.str().c_str());
1091 _families[fname]=famId;
1095 if((*it).second!=famId)
1097 std::ostringstream oss;
1098 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1099 throw INTERP_KERNEL::Exception(oss.str().c_str());
1105 * Creates a group including all mesh entities of given dimension.
1106 * \warning This method does \b not guarantee that the created group includes mesh
1107 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1108 * present in family fields of different dimensions. To assure this, call
1109 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1110 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1112 * \param [in] groupName - a name of the new group.
1113 * \throw If a group named \a groupName already exists.
1114 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1115 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1117 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1119 std::string grpName(groupName);
1120 std::vector<int> levs=getNonEmptyLevelsExt();
1121 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1123 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1124 oss << "Available relative ext levels are : ";
1125 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1126 throw INTERP_KERNEL::Exception(oss.str().c_str());
1128 if(existsGroup(groupName))
1130 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1131 oss << "Already existing groups are : ";
1132 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1133 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1134 throw INTERP_KERNEL::Exception(oss.str().c_str());
1136 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1138 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1139 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1140 std::vector<std::string> familiesOnWholeGroup;
1141 for(const int *it=famIds->begin();it!=famIds->end();it++)
1144 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1146 _groups[grpName]=familiesOnWholeGroup;
1150 * Ensures that given family ids do not present in family fields of dimensions different
1151 * than given ones. If a family id is present in the family fields of dimensions different
1152 * than the given ones, a new family is created and the whole data is updated accordingly.
1153 * \param [in] famIds - a sequence of family ids to check.
1154 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1155 * famIds should exclusively belong.
1156 * \return bool - \c true if no modification is done in \a this mesh by this method.
1158 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1160 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1161 std::vector<int> levs=getNonEmptyLevelsExt();
1162 std::set<int> levs2(levs.begin(),levs.end());
1163 std::vector<int> levsToTest;
1164 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1165 std::set<int> famIds2(famIds.begin(),famIds.end());
1168 if(!_families.empty())
1169 maxFamId=getMaxFamilyId()+1;
1170 std::vector<std::string> allFams=getFamiliesNames();
1171 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1173 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1176 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1177 std::vector<int> tmp;
1178 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1179 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1182 std::string famName=getFamilyNameGivenId(*it2);
1183 std::ostringstream oss; oss << "Family_" << maxFamId;
1184 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1185 addFamilyOnAllGroupsHaving(famName,zeName);
1186 _families[zeName]=maxFamId;
1187 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1196 * Adds a family to a given group in \a this mesh. If the group with a given name does
1197 * not exist, it is created.
1198 * \param [in] grpName - the name of the group to add the family in.
1199 * \param [in] famName - the name of the family to add to the group named \a grpName.
1200 * \throw If \a grpName or \a famName is an empty string.
1201 * \throw If no family named \a famName is present in \a this mesh.
1203 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1205 std::string grpn(grpName);
1206 std::string famn(famName);
1207 if(grpn.empty() || famn.empty())
1208 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1209 std::vector<std::string> fams=getFamiliesNames();
1210 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1212 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1213 oss << "Create this family or choose an existing one ! Existing fams are : ";
1214 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1215 throw INTERP_KERNEL::Exception(oss.str().c_str());
1217 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1218 if(it==_groups.end())
1220 _groups[grpn].push_back(famn);
1224 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1225 if(it2==(*it).second.end())
1226 (*it).second.push_back(famn);
1231 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1232 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1233 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1235 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1237 std::string famNameCpp(famName);
1238 std::string otherCpp(otherFamName);
1239 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1241 std::vector<std::string>& v=(*it).second;
1242 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1244 v.push_back(otherCpp);
1250 * \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).
1251 * \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)
1253 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1256 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1257 std::string grpName(ids->getName());
1259 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1260 ids->checkStrictlyMonotonic(true);
1261 famArr->incrRef(); MCAuto<DataArrayInt> famArrTmp(famArr);
1262 std::vector<std::string> grpsNames=getGroupsNames();
1263 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1265 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1266 throw INTERP_KERNEL::Exception(oss.str().c_str());
1268 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1269 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1270 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1271 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1272 std::vector<int> familyIds;
1273 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1274 int maxVal=getTheMaxAbsFamilyId()+1;
1275 std::map<std::string,int> families(_families);
1276 std::map<std::string, std::vector<std::string> > groups(_groups);
1277 std::vector<std::string> fams;
1278 bool created(false);
1279 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1281 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1282 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1283 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1284 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1287 bool isFamPresent=false;
1288 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1289 isFamPresent=(*itl)->presenceOfValue(*famId);
1291 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1294 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1295 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1296 fams.push_back(locFamName);
1297 if(existsFamily(*famId))
1299 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1300 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1303 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1307 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1308 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1309 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1310 if(existsFamily(*famId))
1312 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1313 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1318 for(std::size_t i=0;i<familyIds.size();i++)
1320 DataArrayInt *da=idsPerfamiliyIds[i];
1321 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1325 _groups[grpName]=fams;
1328 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1330 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1333 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1335 std::string fam(familyNameToChange);
1336 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1338 std::vector<std::string>& fams((*it).second);
1339 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1343 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1349 * Returns a name of the family having a given id or, if no such a family exists, creates
1350 * a new uniquely named family and returns its name.
1351 * \param [in] id - the id of the family whose name is required.
1352 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1353 * \return std::string - the name of the existing or the created family.
1354 * \throw If it is not possible to create a unique family name.
1356 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1358 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1362 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1363 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1364 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1365 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1367 * This method will throws an exception if it is not possible to create a unique family name.
1369 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1371 std::vector<std::string> famAlreadyExisting(families.size());
1373 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1375 if((*it).second!=id)
1377 famAlreadyExisting[ii]=(*it).first;
1386 std::ostringstream oss; oss << "Family_" << id;
1387 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1393 * Sets names and ids of all families in \a this mesh.
1394 * \param [in] info - a map of a family name to a family id.
1396 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1402 * Sets names of all groups and families constituting them in \a this mesh.
1403 * \param [in] info - a map of a group name to a vector of names of families
1404 * constituting the group.
1406 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1412 * Returns an id of the family having a given name.
1413 * \param [in] name - the name of the family of interest.
1414 * \return int - the id of the family of interest.
1415 * \throw If no family with such a \a name exists.
1417 int MEDFileMesh::getFamilyId(const std::string& name) const
1419 std::map<std::string, int>::const_iterator it=_families.find(name);
1420 if(it==_families.end())
1422 std::vector<std::string> fams(getFamiliesNames());
1423 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1424 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1425 throw INTERP_KERNEL::Exception(oss.str().c_str());
1427 return (*it).second;
1431 * Returns ids of the families having given names.
1432 * \param [in] fams - a sequence of the names of families of interest.
1433 * \return std::vector<int> - a sequence of the ids of families of interest.
1434 * \throw If \a fams contains a name of an inexistent family.
1436 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1438 std::vector<int> ret(fams.size());
1440 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1442 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1443 if(it2==_families.end())
1445 std::vector<std::string> fams2=getFamiliesNames();
1446 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1447 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1448 throw INTERP_KERNEL::Exception(oss.str().c_str());
1450 ret[i]=(*it2).second;
1456 * Returns a maximal abs(id) of families in \a this mesh.
1457 * \return int - the maximal norm of family id.
1458 * \throw If there are no families in \a this mesh.
1460 int MEDFileMesh::getMaxAbsFamilyId() const
1462 if(_families.empty())
1463 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1464 int ret=-std::numeric_limits<int>::max();
1465 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1467 ret=std::max(std::abs((*it).second),ret);
1473 * Returns a maximal id of families in \a this mesh.
1474 * \return int - the maximal family id.
1475 * \throw If there are no families in \a this mesh.
1477 int MEDFileMesh::getMaxFamilyId() const
1479 if(_families.empty())
1480 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1481 int ret=-std::numeric_limits<int>::max();
1482 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1484 ret=std::max((*it).second,ret);
1490 * Returns a minimal id of families in \a this mesh.
1491 * \return int - the minimal family id.
1492 * \throw If there are no families in \a this mesh.
1494 int MEDFileMesh::getMinFamilyId() const
1496 if(_families.empty())
1497 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1498 int ret=std::numeric_limits<int>::max();
1499 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1501 ret=std::min((*it).second,ret);
1507 * Returns a maximal id of families in \a this mesh. Not only named families are
1508 * considered but all family fields as well.
1509 * \return int - the maximal family id.
1511 int MEDFileMesh::getTheMaxAbsFamilyId() const
1513 int m1=-std::numeric_limits<int>::max();
1514 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1515 m1=std::max(std::abs((*it).second),m1);
1516 int m2=getMaxAbsFamilyIdInArrays();
1517 return std::max(m1,m2);
1521 * Returns a maximal id of families in \a this mesh. Not only named families are
1522 * considered but all family fields as well.
1523 * \return int - the maximal family id.
1525 int MEDFileMesh::getTheMaxFamilyId() const
1527 int m1=-std::numeric_limits<int>::max();
1528 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1529 m1=std::max((*it).second,m1);
1530 int m2=getMaxFamilyIdInArrays();
1531 return std::max(m1,m2);
1535 * Returns a minimal id of families in \a this mesh. Not only named families are
1536 * considered but all family fields as well.
1537 * \return int - the minimal family id.
1539 int MEDFileMesh::getTheMinFamilyId() const
1541 int m1=std::numeric_limits<int>::max();
1542 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1543 m1=std::min((*it).second,m1);
1544 int m2=getMinFamilyIdInArrays();
1545 return std::min(m1,m2);
1549 * This method only considers the maps. The contain of family array is ignored here.
1551 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1553 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1555 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1557 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1558 v.insert((*it).second);
1559 ret->alloc((int)v.size(),1);
1560 std::copy(v.begin(),v.end(),ret->getPointer());
1565 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1567 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1569 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1571 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1572 MCAuto<DataArrayInt> ret;
1573 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1575 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1576 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1577 if((DataArrayInt *) ret)
1578 ret=dv->buildUnion(ret);
1586 * true is returned if no modification has been needed. false if family
1587 * renumbering has been needed.
1589 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1591 std::vector<int> levs=getNonEmptyLevelsExt();
1592 std::set<int> allFamIds;
1593 int maxId=getMaxFamilyId()+1;
1594 std::map<int,std::vector<int> > famIdsToRenum;
1595 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1597 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1600 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1602 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1604 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1606 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1609 if(famIdsToRenum.empty())
1611 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1612 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1614 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1615 int *famIdsToChange=fam->getPointer();
1616 std::map<int,int> ren;
1617 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1619 if(allIds->presenceOfValue(*it3))
1621 std::string famName=getFamilyNameGivenId(*it3);
1622 std::vector<std::string> grps=getGroupsOnFamily(famName);
1625 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1626 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1627 addFamilyOnGrp((*it4),newFam);
1630 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1631 for(const int *id=ids->begin();id!=ids->end();id++)
1632 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1638 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1639 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1640 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1641 * This method will throw an exception if a same family id is detected in different level.
1642 * \warning This policy is the opposite of those in MED file documentation ...
1644 void MEDFileMesh::normalizeFamIdsTrio()
1646 ensureDifferentFamIdsPerLevel();
1647 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1648 std::vector<int> levs=getNonEmptyLevelsExt();
1649 std::set<int> levsS(levs.begin(),levs.end());
1650 std::set<std::string> famsFetched;
1651 std::map<std::string,int> families;
1652 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1655 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1659 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1660 std::map<int,int> ren;
1661 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1663 int nbOfTuples=fam->getNumberOfTuples();
1664 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1665 for(int *w=start;w!=start+nbOfTuples;w++)
1667 for(const int *it=tmp->begin();it!=tmp->end();it++)
1669 if(allIds->presenceOfValue(*it))
1671 std::string famName=getFamilyNameGivenId(*it);
1672 families[famName]=ren[*it];
1673 famsFetched.insert(famName);
1678 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1681 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1685 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1686 std::map<int,int> ren;
1687 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1689 int nbOfTuples=fam->getNumberOfTuples();
1690 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1691 for(int *w=start;w!=start+nbOfTuples;w++)
1693 for(const int *it=tmp->begin();it!=tmp->end();it++)
1695 if(allIds->presenceOfValue(*it))
1697 std::string famName=getFamilyNameGivenId(*it);
1698 families[famName]=ren[*it];
1699 famsFetched.insert(famName);
1704 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1706 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1709 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1710 fam->fillWithZero();
1711 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1712 if(allIds->presenceOfValue(*it3))
1714 std::string famName=getFamilyNameGivenId(*it3);
1715 families[famName]=0;
1716 famsFetched.insert(famName);
1721 std::vector<std::string> allFams=getFamiliesNames();
1722 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1723 std::set<std::string> unFetchedIds;
1724 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1725 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1726 families[*it4]=_families[*it4];
1731 * This method normalizes fam id with the following policy.
1732 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1733 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1734 * This method will throw an exception if a same family id is detected in different level.
1736 void MEDFileMesh::normalizeFamIdsMEDFile()
1738 ensureDifferentFamIdsPerLevel();
1739 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1740 std::vector<int> levs=getNonEmptyLevelsExt();
1741 std::set<int> levsS(levs.begin(),levs.end());
1742 std::set<std::string> famsFetched;
1743 std::map<std::string,int> families;
1745 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1748 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1751 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1752 std::map<int,int> ren;
1753 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1755 int nbOfTuples=fam->getNumberOfTuples();
1756 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1757 for(int *w=start;w!=start+nbOfTuples;w++)
1759 for(const int *it=tmp->begin();it!=tmp->end();it++)
1761 if(allIds->presenceOfValue(*it))
1763 std::string famName=getFamilyNameGivenId(*it);
1764 families[famName]=ren[*it];
1765 famsFetched.insert(famName);
1771 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1773 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1776 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1777 std::map<int,int> ren;
1778 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1780 int nbOfTuples=fam->getNumberOfTuples();
1781 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1782 for(int *w=start;w!=start+nbOfTuples;w++)
1784 for(const int *it=tmp->begin();it!=tmp->end();it++)
1786 if(allIds->presenceOfValue(*it))
1788 std::string famName=getFamilyNameGivenId(*it);
1789 families[famName]=ren[*it];
1790 famsFetched.insert(famName);
1796 std::vector<std::string> allFams=getFamiliesNames();
1797 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1798 std::set<std::string> unFetchedIds;
1799 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1800 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1801 families[*it4]=_families[*it4];
1806 * Returns a name of the family by its id. If there are several families having the given
1807 * id, the name first in lexical order is returned.
1808 * \param [in] id - the id of the family whose name is required.
1809 * \return std::string - the name of the found family.
1810 * \throw If no family with the given \a id exists.
1812 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1814 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1815 if((*it).second==id)
1817 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1818 throw INTERP_KERNEL::Exception(oss.str().c_str());
1822 * Returns a string describing \a this mesh. This description includes the mesh name and
1823 * the mesh description string.
1824 * \return std::string - the mesh information string.
1826 std::string MEDFileMesh::simpleRepr() const
1828 std::ostringstream oss;
1829 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1830 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1831 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1836 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1837 * an empty one is created.
1839 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1841 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1844 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1845 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1846 arr->fillWithZero();
1847 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1848 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1852 * Returns ids of mesh entities contained in a given group of a given dimension.
1853 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1855 * \param [in] grp - the name of the group of interest.
1856 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1857 * returned instead of ids.
1858 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1859 * numbers, if available and required, of mesh entities of the group. The caller
1860 * is to delete this array using decrRef() as it is no more needed.
1861 * \throw If the name of a nonexistent group is specified.
1862 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1864 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1866 std::vector<std::string> tmp(1);
1868 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1874 * Returns ids of mesh entities contained in given groups of a given dimension.
1875 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1877 * \param [in] grps - the names of the groups of interest.
1878 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1879 * returned instead of ids.
1880 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1881 * numbers, if available and required, of mesh entities of the groups. The caller
1882 * is to delete this array using decrRef() as it is no more needed.
1883 * \throw If the name of a nonexistent group is present in \a grps.
1884 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1886 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1888 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1889 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1893 * Returns ids of mesh entities contained in a given family of a given dimension.
1894 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1896 * \param [in] fam - the name of the family of interest.
1897 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1898 * returned instead of ids.
1899 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1900 * numbers, if available and required, of mesh entities of the family. The caller
1901 * is to delete this array using decrRef() as it is no more needed.
1902 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1904 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1906 std::vector<std::string> tmp(1);
1908 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1914 * Returns ids of nodes contained in a given group.
1915 * \param [in] grp - the name of the group of interest.
1916 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1917 * returned instead of ids.
1918 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1919 * numbers, if available and required, of nodes of the group. The caller
1920 * is to delete this array using decrRef() as it is no more needed.
1921 * \throw If the name of a nonexistent group is specified.
1922 * \throw If the family field is missing for nodes.
1924 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1926 std::vector<std::string> tmp(1);
1928 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1934 * Returns ids of nodes contained in given groups.
1935 * \param [in] grps - the names of the groups of interest.
1936 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1937 * returned instead of ids.
1938 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1939 * numbers, if available and required, of nodes of the groups. The caller
1940 * is to delete this array using decrRef() as it is no more needed.
1941 * \throw If the name of a nonexistent group is present in \a grps.
1942 * \throw If the family field is missing for nodes.
1944 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1946 return getGroupsArr(1,grps,renum);
1950 * Returns ids of nodes contained in a given group.
1951 * \param [in] grp - the name of the group of interest.
1952 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1953 * returned instead of ids.
1954 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1955 * numbers, if available and required, of nodes of the group. The caller
1956 * is to delete this array using decrRef() as it is no more needed.
1957 * \throw If the name of a nonexistent group is specified.
1958 * \throw If the family field is missing for nodes.
1960 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1962 std::vector<std::string> tmp(1);
1964 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1970 * Returns ids of nodes contained in given families.
1971 * \param [in] fams - the names of the families of interest.
1972 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1973 * returned instead of ids.
1974 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1975 * numbers, if available and required, of nodes of the families. The caller
1976 * is to delete this array using decrRef() as it is no more needed.
1977 * \throw If the family field is missing for nodes.
1979 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1981 return getFamiliesArr(1,fams,renum);
1985 * Adds groups of given dimension and creates corresponding families and family fields
1986 * given ids of mesh entities of each group.
1987 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1988 * \param [in] grps - a sequence of arrays of ids each describing a group.
1989 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1991 * \throw If names of some groups in \a grps are equal.
1992 * \throw If \a grps includes a group with an empty name.
1993 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1994 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1996 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2000 std::set<std::string> grpsName;
2001 std::vector<std::string> grpsName2(grps.size());
2004 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2006 grpsName.insert((*it)->getName());
2007 grpsName2[i]=(*it)->getName();
2009 if(grpsName.size()!=grps.size())
2010 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2011 if(grpsName.find(std::string(""))!=grpsName.end())
2012 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2013 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2014 MCAuto<DataArrayInt> fam;
2015 std::vector< std::vector<int> > fidsOfGroups;
2018 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2022 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2023 for(unsigned int ii=0;ii<grps.size();ii++)
2025 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2026 grps2[ii]->setName(grps[ii]->getName());
2028 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2029 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2032 if(!_families.empty())
2033 offset=getMaxAbsFamilyId()+1;
2034 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2035 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2036 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2037 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2041 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2042 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2043 * For the moment, the two last input parameters are not taken into account.
2045 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2047 std::map<int,std::string> famInv;
2048 for(const int *it=famIds->begin();it!=famIds->end();it++)
2050 std::ostringstream oss;
2051 oss << "Family_" << (*it);
2052 _families[oss.str()]=(*it);
2053 famInv[*it]=oss.str();
2056 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2058 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2060 _groups[grpNames[i]].push_back(famInv[*it2]);
2065 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2067 std::vector<int> levs(getNonEmptyLevels());
2068 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2069 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2071 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2072 ret.insert(ret.end(),elts.begin(),elts.end());
2078 * \sa getAllDistributionOfTypes
2080 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2082 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2083 return mLev->getDistributionOfTypes();
2086 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2088 loadLL(fid,mName,dt,it,mrs);
2089 loadJointsFromFile(fid);
2090 loadEquivalences(fid);
2093 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2095 famArr->applyLin(offset>0?1:-1,offset,0);
2096 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2099 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2100 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2105 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2106 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2107 * If this method fails to find such a name it will throw an exception.
2109 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2112 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2115 std::size_t len=nameTry.length();
2116 for(std::size_t ii=1;ii<len;ii++)
2118 std::string tmp=nameTry.substr(ii,len-ii);
2119 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2125 for(std::size_t i=1;i<30;i++)
2127 std::string tmp1(nameTry.at(0),i);
2129 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2135 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2137 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2139 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2142 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2144 std::size_t nbOfChunks=code.size()/3;
2145 if(code.size()%3!=0)
2146 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2148 for(std::size_t i=0;i<nbOfChunks;i++)
2157 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2158 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2159 * If _name is not empty and that 'm' has the same name nothing is done.
2160 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2162 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2165 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2170 std::string name(m->getName());
2175 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2176 oss << name << "' ! Names must match !";
2177 throw INTERP_KERNEL::Exception(oss.str().c_str());
2181 if(_desc_name.empty())
2182 _desc_name=m->getDescription();
2185 std::string name(m->getDescription());
2188 if(_desc_name!=name)
2190 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2191 oss << name << "' ! Names must match !";
2192 throw INTERP_KERNEL::Exception(oss.str().c_str());
2198 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2200 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2201 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2203 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2204 oss << " - Groups lying on this family : ";
2205 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2206 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2207 oss << std::endl << std::endl;
2212 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2213 * file. The mesh to load is specified by its name and numbers of a time step and an
2215 * \param [in] fileName - the name of MED file to read.
2216 * \param [in] mName - the name of the mesh to read.
2217 * \param [in] dt - the number of a time step.
2218 * \param [in] it - the number of an iteration.
2219 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2220 * mesh using decrRef() as it is no more needed.
2221 * \throw If the file is not readable.
2222 * \throw If there is no mesh with given attributes in the file.
2223 * \throw If the mesh in the file is not an unstructured one.
2225 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2227 MEDFileUtilities::CheckFileForRead(fileName);
2228 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2229 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2233 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2234 * file. The first mesh in the file is loaded.
2235 * \param [in] fileName - the name of MED file to read.
2236 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2237 * mesh using decrRef() as it is no more needed.
2238 * \throw If the file is not readable.
2239 * \throw If there is no meshes in the file.
2240 * \throw If the mesh in the file is not an unstructured one.
2242 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2244 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
2247 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2248 throw INTERP_KERNEL::Exception(oss.str().c_str());
2250 MEDFileUtilities::CheckFileForRead(fileName);
2251 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2253 MEDCoupling::MEDCouplingMeshType meshType;
2255 MEDCoupling::MEDCouplingAxisType dummy3;
2256 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2257 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2261 * \b WARNING this implementation is dependant from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2262 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2264 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2267 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2268 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2269 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2270 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2272 m2D->setCoords(m3D->getCoords());
2273 ret->setMeshAtLevel(0,m3D);
2274 ret->setMeshAtLevel(-1,m2D);
2275 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2280 * Returns an empty instance of MEDFileUMesh.
2281 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2282 * mesh using decrRef() as it is no more needed.
2284 MEDFileUMesh *MEDFileUMesh::New()
2286 return new MEDFileUMesh;
2290 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2291 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2292 * \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.
2293 * 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
2294 * at most the memory consumtion.
2296 * \param [in] fileName - the name of the file.
2297 * \param [in] mName - the name of the mesh to be read.
2298 * \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.
2299 * \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.
2300 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2301 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2302 * \param [in] mrs - the request for what to be loaded.
2303 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2305 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)
2307 MEDFileUtilities::CheckFileForRead(fileName);
2308 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2309 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2313 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2314 * This method is \b NOT wrapped into python.
2316 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)
2318 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2319 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2323 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2325 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2326 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>));
2330 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2332 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2333 ret.push_back((const DataArrayDouble*)_coords);
2334 ret.push_back((const DataArrayInt *)_fam_coords);
2335 ret.push_back((const DataArrayInt *)_num_coords);
2336 ret.push_back((const DataArrayInt *)_rev_num_coords);
2337 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2338 ret.push_back((const PartDefinition *)_part_coords);
2339 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2340 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2344 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2346 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2350 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2352 return new MEDFileUMesh;
2355 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2357 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2358 ret->deepCpyEquivalences(*this);
2359 if((const DataArrayDouble*)_coords)
2360 ret->_coords=_coords->deepCopy();
2361 if((const DataArrayInt*)_fam_coords)
2362 ret->_fam_coords=_fam_coords->deepCopy();
2363 if((const DataArrayInt*)_num_coords)
2364 ret->_num_coords=_num_coords->deepCopy();
2365 if((const DataArrayInt*)_rev_num_coords)
2366 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2367 if((const DataArrayAsciiChar*)_name_coords)
2368 ret->_name_coords=_name_coords->deepCopy();
2370 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2372 if((const MEDFileUMeshSplitL1 *)(*it))
2373 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2375 if((const PartDefinition*)_part_coords)
2376 ret->_part_coords=_part_coords->deepCopy();
2381 * Checks if \a this and another mesh are equal.
2382 * \param [in] other - the mesh to compare with.
2383 * \param [in] eps - a precision used to compare real values.
2384 * \param [in,out] what - the string returning description of unequal data.
2385 * \return bool - \c true if the meshes are equal, \c false, else.
2387 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2389 if(!MEDFileMesh::isEqual(other,eps,what))
2391 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2394 what="Mesh types differ ! This is unstructured and other is NOT !";
2397 clearNonDiscrAttributes();
2398 otherC->clearNonDiscrAttributes();
2399 const DataArrayDouble *coo1=_coords;
2400 const DataArrayDouble *coo2=otherC->_coords;
2401 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2403 what="Mismatch of coordinates ! One is defined and not other !";
2408 bool ret=coo1->isEqual(*coo2,eps);
2411 what="Coords differ !";
2415 const DataArrayInt *famc1=_fam_coords;
2416 const DataArrayInt *famc2=otherC->_fam_coords;
2417 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2419 what="Mismatch of families arr on nodes ! One is defined and not other !";
2424 bool ret=famc1->isEqual(*famc2);
2427 what="Families arr on node differ !";
2431 const DataArrayInt *numc1=_num_coords;
2432 const DataArrayInt *numc2=otherC->_num_coords;
2433 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2435 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2440 bool ret=numc1->isEqual(*numc2);
2443 what="Numbering arr on node differ !";
2447 const DataArrayAsciiChar *namec1=_name_coords;
2448 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2449 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2451 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2456 bool ret=namec1->isEqual(*namec2);
2459 what="Names arr on node differ !";
2463 if(_ms.size()!=otherC->_ms.size())
2465 what="Number of levels differs !";
2468 std::size_t sz=_ms.size();
2469 for(std::size_t i=0;i<sz;i++)
2471 const MEDFileUMeshSplitL1 *s1=_ms[i];
2472 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2473 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2475 what="Mismatch of presence of sub levels !";
2480 bool ret=s1->isEqual(s2,eps,what);
2485 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2488 if((!pd0 && pd1) || (pd0 && !pd1))
2490 what=std::string("node part def is defined only for one among this or other !");
2493 return pd0->isEqual(pd1,what);
2497 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2498 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2499 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2500 * \throw if internal family array is inconsistent
2501 * \sa checkSMESHConsistency()
2503 void MEDFileUMesh::checkConsistency() const
2505 if(!_coords || !_coords->isAllocated())
2508 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2510 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2511 if (!_num_coords || !_rev_num_coords)
2512 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2516 int nbCoo = _coords->getNumberOfTuples();
2518 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2521 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2523 int maxValue=_num_coords->getMaxValue(pos);
2524 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2525 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2527 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2528 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2529 if (_num_coords && !_num_coords->hasUniqueValues())
2530 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2532 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2533 // Now sub part check:
2534 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2535 it != _ms.end(); it++)
2536 (*it)->checkConsistency();
2541 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2542 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2543 * entities as it likes), or non overlapping between all sub-levels.
2544 * \throw if the condition above is not respected
2546 void MEDFileUMesh::checkSMESHConsistency() const
2549 // For all sub-levels, numbering is either always null or with void intersection:
2552 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2553 std::vector< const DataArrayInt * > v;
2554 bool voidOrNot = ((*it)->_num == 0);
2555 for (it++; it != _ms.end(); it++)
2556 if( ((*it)->_num == 0) != voidOrNot )
2557 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2558 else if (!voidOrNot)
2559 v.push_back((*it)->_num);
2562 // don't forget the 1st one:
2563 v.push_back(_ms[0]->_num);
2564 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2565 if (inter->getNumberOfTuples())
2566 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2572 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2573 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2575 void MEDFileUMesh::clearNodeAndCellNumbers()
2578 _rev_num_coords = 0;
2579 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2580 it != _ms.end(); it++)
2583 (*it)->_rev_num = 0;
2588 * Clears redundant attributes of incorporated data arrays.
2590 void MEDFileUMesh::clearNonDiscrAttributes() const
2592 MEDFileMesh::clearNonDiscrAttributes();
2593 const DataArrayDouble *coo1=_coords;
2595 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2596 const DataArrayInt *famc1=_fam_coords;
2598 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2599 const DataArrayInt *numc1=_num_coords;
2601 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2602 const DataArrayAsciiChar *namc1=_name_coords;
2604 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2605 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2607 const MEDFileUMeshSplitL1 *tmp=(*it);
2609 tmp->clearNonDiscrAttributes();
2613 void MEDFileUMesh::setName(const std::string& name)
2615 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2616 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2617 (*it)->setName(name);
2618 MEDFileMesh::setName(name);
2621 MEDFileUMesh::MEDFileUMesh()
2625 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2628 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2630 catch(INTERP_KERNEL::Exception& e)
2636 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2637 * See MEDFileUMesh::LoadPartOf for detailed description.
2641 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)
2643 MEDFileUMeshL2 loaderl2;
2644 MEDCoupling::MEDCouplingMeshType meshType;
2647 MEDCoupling::MEDCouplingAxisType dummy3;
2648 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2649 if(meshType!=UNSTRUCTURED)
2651 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2652 throw INTERP_KERNEL::Exception(oss.str().c_str());
2654 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2655 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2659 * \brief Write joints in a file
2661 void MEDFileMesh::writeJoints(med_idt fid) const
2663 if ( _joints.isNotNull() )
2664 _joints->writeLL(fid);
2668 * \brief Load joints in a file or use provided ones
2670 //================================================================================
2672 * \brief Load joints in a file or use provided ones
2673 * \param [in] fid - MED file descriptor
2674 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2675 * Usually this joints are those just read by another iteration
2676 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2678 //================================================================================
2680 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2682 if ( toUseInstedOfReading )
2683 setJoints( toUseInstedOfReading );
2685 _joints = MEDFileJoints::New( fid, _name );
2688 void MEDFileMesh::loadEquivalences(med_idt fid)
2690 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2692 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2695 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2697 const MEDFileEquivalences *equiv(other._equiv);
2699 _equiv=equiv->deepCopy(this);
2702 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2704 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2705 if(!thisEq && !otherEq)
2707 if(thisEq && otherEq)
2708 return thisEq->isEqual(otherEq,what);
2711 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2716 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2718 const MEDFileEquivalences *equiv(_equiv);
2721 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2722 _equiv->getRepr(oss);
2725 void MEDFileMesh::checkCartesian() const
2727 if(getAxisType()!=AX_CART)
2729 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()) << ").";
2730 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2731 oss << " - call setAxisType(AX_CART)" << std::endl;
2732 oss << " - call cartesianize()";
2733 throw INTERP_KERNEL::Exception(oss.str().c_str());
2738 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2740 int MEDFileMesh::getNumberOfJoints() const
2742 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2746 * \brief Return joints with all adjacent mesh domains
2748 MEDFileJoints * MEDFileMesh::getJoints() const
2750 return const_cast<MEDFileJoints*>(& (*_joints));
2753 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2755 if ( joints != _joints )
2764 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2766 * \sa loadPartUMeshFromFile
2768 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2770 MEDFileUMeshL2 loaderl2;
2771 MEDCoupling::MEDCouplingMeshType meshType;
2774 MEDCoupling::MEDCouplingAxisType axType;
2775 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2776 setAxisType(axType);
2777 if(meshType!=UNSTRUCTURED)
2779 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2780 throw INTERP_KERNEL::Exception(oss.str().c_str());
2782 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2783 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2786 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2788 int lev=loaderl2.getNumberOfLevels();
2790 for(int i=0;i<lev;i++)
2792 if(!loaderl2.emptyLev(i))
2793 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2797 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2799 setName(loaderl2.getName());
2800 setDescription(loaderl2.getDescription());
2801 setUnivName(loaderl2.getUnivName());
2802 setIteration(loaderl2.getIteration());
2803 setOrder(loaderl2.getOrder());
2804 setTimeValue(loaderl2.getTime());
2805 setTimeUnit(loaderl2.getTimeUnit());
2806 _coords=loaderl2.getCoords();
2807 if(!mrs || mrs->isNodeFamilyFieldReading())
2808 _fam_coords=loaderl2.getCoordsFamily();
2809 if(!mrs || mrs->isNodeNumFieldReading())
2810 _num_coords=loaderl2.getCoordsNum();
2811 if(!mrs || mrs->isNodeNameFieldReading())
2812 _name_coords=loaderl2.getCoordsName();
2813 _part_coords=loaderl2.getPartDefOfCoo();
2817 MEDFileUMesh::~MEDFileUMesh()
2821 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2823 const DataArrayDouble *coo=_coords;
2824 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2825 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2826 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2827 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2828 int spaceDim=coo?coo->getNumberOfComponents():0;
2831 mdim=getMeshDimension();
2832 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2833 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2834 for(int i=0;i<spaceDim;i++)
2836 std::string info=coo->getInfoOnComponent(i);
2838 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2839 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
2840 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
2842 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2844 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2845 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2846 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2847 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2848 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2849 (*it)->write(fid,meshName,mdim);
2850 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2854 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2855 * \return std::vector<int> - a sequence of the relative dimensions.
2857 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2859 std::vector<int> ret;
2861 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2862 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2869 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2870 * \return std::vector<int> - a sequence of the relative dimensions.
2872 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2874 std::vector<int> ret0=getNonEmptyLevels();
2875 if((const DataArrayDouble *) _coords)
2877 std::vector<int> ret(ret0.size()+1);
2879 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2885 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2887 std::vector<int> ret;
2888 const DataArrayInt *famCoo(_fam_coords);
2892 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2894 const MEDFileUMeshSplitL1 *cur(*it);
2896 if(cur->getFamilyField())
2902 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2904 std::vector<int> ret;
2905 const DataArrayInt *numCoo(_num_coords);
2909 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2911 const MEDFileUMeshSplitL1 *cur(*it);
2913 if(cur->getNumberField())
2919 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2921 std::vector<int> ret;
2922 const DataArrayAsciiChar *nameCoo(_name_coords);
2926 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2928 const MEDFileUMeshSplitL1 *cur(*it);
2930 if(cur->getNameField())
2937 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2938 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2939 * \param [in] fams - the name of the family of interest.
2940 * \return std::vector<int> - a sequence of the relative dimensions.
2942 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2944 std::vector<int> ret;
2945 std::vector<int> levs(getNonEmptyLevels());
2946 std::vector<int> famIds(getFamiliesIds(fams));
2947 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2948 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2954 * Returns all relative mesh levels (including nodes) where given families are defined.
2955 * \param [in] fams - the names of the families of interest.
2956 * \return std::vector<int> - a sequence of the relative dimensions.
2958 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2960 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2961 const DataArrayInt *famCoords(_fam_coords);
2964 std::vector<int> famIds(getFamiliesIds(fams));
2965 if(famCoords->presenceOfValue(famIds))
2967 std::vector<int> ret(ret0.size()+1);
2969 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2976 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2978 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2979 if((const DataArrayInt *)_fam_coords)
2981 int val=_fam_coords->getMaxValue(tmp);
2982 ret=std::max(ret,std::abs(val));
2984 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2986 if((const MEDFileUMeshSplitL1 *)(*it))
2988 const DataArrayInt *da=(*it)->getFamilyField();
2991 int val=da->getMaxValue(tmp);
2992 ret=std::max(ret,std::abs(val));
2999 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3001 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3002 if((const DataArrayInt *)_fam_coords)
3004 int val=_fam_coords->getMaxValue(tmp);
3005 ret=std::max(ret,val);
3007 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3009 if((const MEDFileUMeshSplitL1 *)(*it))
3011 const DataArrayInt *da=(*it)->getFamilyField();
3014 int val=da->getMaxValue(tmp);
3015 ret=std::max(ret,val);
3022 int MEDFileUMesh::getMinFamilyIdInArrays() const
3024 int ret=std::numeric_limits<int>::max(),tmp=-1;
3025 if((const DataArrayInt *)_fam_coords)
3027 int val=_fam_coords->getMinValue(tmp);
3028 ret=std::min(ret,val);
3030 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3032 if((const MEDFileUMeshSplitL1 *)(*it))
3034 const DataArrayInt *da=(*it)->getFamilyField();
3037 int val=da->getMinValue(tmp);
3038 ret=std::min(ret,val);
3046 * Returns the dimension on cells in \a this mesh.
3047 * \return int - the mesh dimension.
3048 * \throw If there are no cells in this mesh.
3050 int MEDFileUMesh::getMeshDimension() const
3053 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3054 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3055 return (*it)->getMeshDimension()+lev;
3056 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3060 * Returns the space dimension of \a this mesh that is equal to number of components in
3061 * the node coordinates array.
3062 * \return int - the space dimension of \a this mesh.
3063 * \throw If the node coordinates array is not available.
3065 int MEDFileUMesh::getSpaceDimension() const
3067 const DataArrayDouble *coo=_coords;
3069 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3070 return coo->getNumberOfComponents();
3074 * Returns a string describing \a this mesh.
3075 * \return std::string - the mesh information string.
3077 std::string MEDFileUMesh::simpleRepr() const
3079 std::ostringstream oss;
3080 oss << MEDFileMesh::simpleRepr();
3081 const DataArrayDouble *coo=_coords;
3082 oss << "- The dimension of the space is ";
3083 static const char MSG1[]= "*** NO COORDS SET ***";
3084 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3086 oss << _coords->getNumberOfComponents() << std::endl;
3088 oss << MSG1 << std::endl;
3089 oss << "- Type of the mesh : UNSTRUCTURED\n";
3090 oss << "- Number of nodes : ";
3092 oss << _coords->getNumberOfTuples() << std::endl;
3094 oss << MSG1 << std::endl;
3095 std::size_t nbOfLev=_ms.size();
3096 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3097 for(std::size_t i=0;i<nbOfLev;i++)
3099 const MEDFileUMeshSplitL1 *lev=_ms[i];
3100 oss << " - Level #" << -((int) i) << " has dimension : ";
3103 oss << lev->getMeshDimension() << std::endl;
3104 lev->simpleRepr(oss);
3107 oss << MSG2 << std::endl;
3109 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3112 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3113 oss << "- Names of coordinates :" << std::endl;
3114 std::vector<std::string> vars=coo->getVarsOnComponent();
3115 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3116 oss << std::endl << "- Units of coordinates : " << std::endl;
3117 std::vector<std::string> units=coo->getUnitsOnComponent();
3118 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3120 oss << std::endl << std::endl;
3122 getEquivalencesRepr(oss);
3127 * Returns a full textual description of \a this mesh.
3128 * \return std::string - the string holding the mesh description.
3130 std::string MEDFileUMesh::advancedRepr() const
3132 return simpleRepr();
3136 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3137 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3138 * \return int - the number of entities.
3139 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3141 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3143 if(meshDimRelToMaxExt==1)
3145 if(!((const DataArrayDouble *)_coords))
3146 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3147 return _coords->getNumberOfTuples();
3149 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3153 * Returns the family field for mesh entities of a given dimension.
3154 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3155 * \return const DataArrayInt * - the family field. It is an array of ids of families
3156 * each mesh entity belongs to. It can be \c NULL.
3158 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3160 if(meshDimRelToMaxExt==1)
3162 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3163 return l1->getFamilyField();
3166 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3168 if(meshDimRelToMaxExt==1)
3170 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3171 return l1->getFamilyField();
3175 * Returns the optional numbers of mesh entities of a given dimension.
3176 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3177 * \return const DataArrayInt * - the array of the entity numbers.
3178 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3180 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3182 if(meshDimRelToMaxExt==1)
3184 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3185 return l1->getNumberField();
3188 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3190 if(meshDimRelToMaxExt==1)
3191 return _name_coords;
3192 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3193 return l1->getNameField();
3197 * 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).
3199 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3200 * \param [in] gt - The input geometric type for which the part definition is requested.
3201 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3203 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3205 if(meshDimRelToMaxExt==1)
3206 return _part_coords;
3207 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3208 return l1->getPartDef(gt);
3211 int MEDFileUMesh::getNumberOfNodes() const
3213 const DataArrayDouble *coo(_coords);
3215 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3216 return coo->getNumberOfTuples();
3219 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3221 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3222 return l1->getNumberOfCells();
3225 bool MEDFileUMesh::hasImplicitPart() const
3230 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3232 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3235 void MEDFileUMesh::releaseImplicitPartIfAny() const
3239 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3241 std::size_t sz(st.getNumberOfItems());
3242 for(std::size_t i=0;i<sz;i++)
3244 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3245 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3246 if(st[i].getPflName().empty())
3247 m->computeNodeIdsAlg(nodesFetched);
3250 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3251 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3252 m2->computeNodeIdsAlg(nodesFetched);
3257 MEDFileMesh *MEDFileUMesh::cartesianize() const
3259 if(getAxisType()==AX_CART)
3262 return const_cast<MEDFileUMesh *>(this);
3266 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3267 const DataArrayDouble *coords(_coords);
3269 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3270 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3271 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3272 if((const MEDFileUMeshSplitL1 *)(*it))
3273 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3274 ret->_coords=coordsCart;
3275 ret->setAxisType(AX_CART);
3281 * Returns the optional numbers of mesh entities of a given dimension transformed using
3282 * DataArrayInt::invertArrayN2O2O2N().
3283 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3284 * \return const DataArrayInt * - the array of the entity numbers transformed using
3285 * DataArrayInt::invertArrayN2O2O2N().
3286 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3288 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3290 if(meshDimRelToMaxExt==1)
3292 if(!((const DataArrayInt *)_num_coords))
3293 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3294 return _rev_num_coords;
3296 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3297 return l1->getRevNumberField();
3301 * Returns a pointer to the node coordinates array of \a this mesh \b without
3302 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3304 DataArrayDouble *MEDFileUMesh::getCoords() const
3307 MCAuto<DataArrayDouble> tmp(_coords);
3308 if((DataArrayDouble *)tmp)
3316 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3317 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3319 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3320 * \param [in] grp - the name of the group whose mesh entities are included in the
3322 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3323 * according to the optional numbers of entities, if available.
3324 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3325 * delete this mesh using decrRef() as it is no more needed.
3326 * \throw If the name of a nonexistent group is specified.
3327 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3329 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3332 synchronizeTinyInfoOnLeaves();
3333 std::vector<std::string> tmp(1);
3335 return getGroups(meshDimRelToMaxExt,tmp,renum);
3339 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3340 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3342 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3343 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3345 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3346 * according to the optional numbers of entities, if available.
3347 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3348 * delete this mesh using decrRef() as it is no more needed.
3349 * \throw If a name of a nonexistent group is present in \a grps.
3350 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3352 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3355 synchronizeTinyInfoOnLeaves();
3356 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3357 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3358 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3359 zeRet->setName(grps[0]);
3360 return zeRet.retn();
3364 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3365 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3367 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3368 * \param [in] fam - the name of the family whose mesh entities are included in the
3370 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3371 * according to the optional numbers of entities, if available.
3372 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3373 * delete this mesh using decrRef() as it is no more needed.
3374 * \throw If a name of a nonexistent family is present in \a grps.
3375 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3377 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3380 synchronizeTinyInfoOnLeaves();
3381 std::vector<std::string> tmp(1);
3383 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3387 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3388 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3390 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3391 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3393 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3394 * according to the optional numbers of entities, if available.
3395 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3396 * delete this mesh using decrRef() as it is no more needed.
3397 * \throw If a name of a nonexistent family is present in \a fams.
3398 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3400 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3403 synchronizeTinyInfoOnLeaves();
3404 if(meshDimRelToMaxExt==1)
3406 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3407 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3408 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3412 std::vector<int> famIds=getFamiliesIds(fams);
3413 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3414 MCAuto<MEDCouplingUMesh> zeRet;
3416 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3418 zeRet=l1->getFamilyPart(0,0,renum);
3419 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3420 zeRet->setName(fams[0]);
3421 return zeRet.retn();
3425 * Returns ids of mesh entities contained in given families of a given dimension.
3426 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3428 * \param [in] fams - the names of the families of interest.
3429 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3430 * returned instead of ids.
3431 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3432 * numbers, if available and required, of mesh entities of the families. The caller
3433 * is to delete this array using decrRef() as it is no more needed.
3434 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3436 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3438 std::vector<int> famIds=getFamiliesIds(fams);
3439 if(meshDimRelToMaxExt==1)
3441 if((const DataArrayInt *)_fam_coords)
3443 MCAuto<DataArrayInt> da;
3445 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3447 da=_fam_coords->findIdsEqualList(0,0);
3449 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3454 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3456 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3458 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3460 return l1->getFamilyPartArr(0,0,renum);
3464 * Returns a MEDCouplingUMesh of a given relative dimension.
3465 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3466 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3467 * To build a valid MEDCouplingUMesh from the returned one in this case,
3468 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3469 * \param [in] meshDimRelToMax - the relative dimension of interest.
3470 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3471 * optional numbers of mesh entities.
3472 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3473 * delete using decrRef() as it is no more needed.
3474 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3476 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3479 synchronizeTinyInfoOnLeaves();
3480 if(meshDimRelToMaxExt==1)
3484 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3485 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3486 umesh->setCoords(cc);
3487 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3488 umesh->setName(getName());
3492 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3493 return l1->getWholeMesh(renum);
3496 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3498 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3499 return l1->getDistributionOfTypes();
3503 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3504 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3505 * optional numbers of mesh entities.
3506 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3507 * delete using decrRef() as it is no more needed.
3508 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3510 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3512 return getMeshAtLevel(0,renum);
3516 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3517 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3518 * optional numbers of mesh entities.
3519 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3520 * delete using decrRef() as it is no more needed.
3521 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3523 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3525 return getMeshAtLevel(-1,renum);
3529 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3530 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3531 * optional numbers of mesh entities.
3532 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3533 * delete using decrRef() as it is no more needed.
3534 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3536 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3538 return getMeshAtLevel(-2,renum);
3542 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3543 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3544 * optional numbers of mesh entities.
3545 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3546 * delete using decrRef() as it is no more needed.
3547 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3549 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3551 return getMeshAtLevel(-3,renum);
3555 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3556 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3557 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3558 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3560 void MEDFileUMesh::forceComputationOfParts() const
3562 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3564 const MEDFileUMeshSplitL1 *elt(*it);
3566 elt->forceComputationOfParts();
3571 * This method returns a vector of mesh parts containing each exactly one geometric type.
3572 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3573 * This method is only for memory aware users.
3574 * The returned pointers are **NOT** new object pointer. No need to mange them.
3576 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3579 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3580 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3584 * This method returns the part of \a this having the geometric type \a gt.
3585 * If such part is not existing an exception will be thrown.
3586 * The returned pointer is **NOT** new object pointer. No need to mange it.
3588 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3591 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3592 int lev=(int)cm.getDimension()-getMeshDimension();
3593 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3594 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3598 * This method returns for each geo types in \a this number of cells with this geo type.
3599 * 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.
3600 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3602 * \sa getDistributionOfTypes
3604 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3606 std::vector< std::pair<int,int> > ret;
3607 std::vector<int> nel(getNonEmptyLevels());
3608 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3610 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3611 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3613 int nbCells(getNumberOfCellsWithType(*it1));
3614 ret.push_back(std::pair<int,int>(*it1,nbCells));
3617 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3622 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3623 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3625 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3627 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3628 return sp->getGeoTypes();
3631 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3633 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3634 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3635 return sp->getNumberOfCellsWithType(ct);
3639 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3640 * \param [in] gt - the geometric type for which the family field is asked.
3641 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3642 * delete using decrRef() as it is no more needed.
3643 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3645 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3647 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3648 int lev=(int)cm.getDimension()-getMeshDimension();
3649 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3650 return sp->extractFamilyFieldOnGeoType(gt);
3654 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3655 * \param [in] gt - the geometric type for which the number field is asked.
3656 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3657 * delete using decrRef() as it is no more needed.
3658 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3660 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3662 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3663 int lev=(int)cm.getDimension()-getMeshDimension();
3664 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3665 return sp->extractNumberFieldOnGeoType(gt);
3669 * This method returns for specified geometric type \a gt the relative level to \a this.
3670 * If the relative level is empty an exception will be thrown.
3672 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3674 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3675 int ret((int)cm.getDimension()-getMeshDimension());
3676 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3680 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3682 if(meshDimRelToMaxExt==1)
3683 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3684 if(meshDimRelToMaxExt>1)
3685 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3686 int tracucedRk=-meshDimRelToMaxExt;
3687 if(tracucedRk>=(int)_ms.size())
3688 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3689 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3690 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3691 return _ms[tracucedRk];
3694 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3696 if(meshDimRelToMaxExt==1)
3697 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3698 if(meshDimRelToMaxExt>1)
3699 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3700 int tracucedRk=-meshDimRelToMaxExt;
3701 if(tracucedRk>=(int)_ms.size())
3702 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3703 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3704 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3705 return _ms[tracucedRk];
3708 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3710 if(-meshDimRelToMax>=(int)_ms.size())
3711 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3713 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3715 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3717 int ref=(*it)->getMeshDimension();
3718 if(ref+i!=meshDim-meshDimRelToMax)
3719 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3725 * Sets the node coordinates array of \a this mesh.
3726 * \param [in] coords - the new node coordinates array.
3727 * \throw If \a coords == \c NULL.
3729 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3732 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3733 if(coords==(DataArrayDouble *)_coords)
3735 coords->checkAllocated();
3736 int nbOfTuples(coords->getNumberOfTuples());
3739 _fam_coords=DataArrayInt::New();
3740 _fam_coords->alloc(nbOfTuples,1);
3741 _fam_coords->fillWithZero();
3742 _num_coords=0; _rev_num_coords=0; _name_coords=0;
3743 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3744 if((MEDFileUMeshSplitL1 *)(*it))
3745 (*it)->setCoords(coords);
3749 * Change coords without changing anything concerning families and numbering on nodes.
3751 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3754 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3755 if(coords==(DataArrayDouble *)_coords)
3757 coords->checkAllocated();
3758 int nbOfTuples(coords->getNumberOfTuples());
3759 if(_coords.isNull())
3766 int oldNbTuples(_coords->getNumberOfTuples());
3767 if(oldNbTuples!=nbOfTuples)
3768 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3772 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3773 if((MEDFileUMeshSplitL1 *)(*it))
3774 (*it)->setCoords(coords);
3778 * Removes all groups of a given dimension in \a this mesh.
3779 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3780 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3782 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3784 if(meshDimRelToMaxExt==1)
3786 if((DataArrayInt *)_fam_coords)
3787 _fam_coords->fillWithZero();
3790 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3791 l1->eraseFamilyField();
3796 * Removes all families with ids not present in the family fields of \a this mesh.
3798 void MEDFileUMesh::optimizeFamilies()
3800 std::vector<int> levs=getNonEmptyLevelsExt();
3801 std::set<int> allFamsIds;
3802 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3804 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3805 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3807 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3810 std::set<std::string> famNamesToKill;
3811 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3813 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3814 famNamesToKill.insert((*it).first);
3816 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3817 _families.erase(*it);
3818 std::vector<std::string> grpNamesToKill;
3819 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3821 std::vector<std::string> tmp;
3822 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3824 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3825 tmp.push_back(*it2);
3830 tmp.push_back((*it).first);
3832 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3837 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3838 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3839 * The boundary is built according to the following method:
3840 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3841 * coordinates array is extended).
3842 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3843 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3844 * might not be duplicated at all.
3845 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3846 * other side of the group is no more a neighbor)
3847 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3848 * bordering the newly created boundary use the newly computed nodes.
3849 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3850 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3852 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3853 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3855 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3856 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3857 * \sa clearNodeAndCellNumbers()
3859 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3860 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3862 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3863 typedef MCAuto<DataArrayInt> DAInt;
3865 std::vector<int> levs=getNonEmptyLevels();
3866 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3867 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3868 MUMesh m0=getMeshAtLevel(0);
3869 MUMesh m1=getMeshAtLevel(-1);
3870 int nbNodes=m0->getNumberOfNodes();
3871 MUMesh m11=getGroup(-1,grpNameM1);
3872 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3873 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3874 DAInt nodeIdsToDuplicate(tmp00);
3875 DAInt cellsToModifyConn0(tmp11);
3876 DAInt cellsToModifyConn1(tmp22);
3877 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3878 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3879 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3880 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3881 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3882 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3883 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3884 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3885 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3886 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3887 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3888 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3889 DAInt grpIds=getGroupArr(-1,grpNameM1);
3890 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3891 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3892 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3893 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3894 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3895 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3896 m0->setCoords(tmp0->getCoords());
3897 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3898 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3899 m1->setCoords(m0->getCoords());
3900 _coords=m0->getCoords(); _coords->incrRef();
3901 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3902 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3903 DataArrayInt * duplCells;
3904 m1->areCellsIncludedIn(m11, 0, duplCells);
3905 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3906 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3907 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3908 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3909 DAInt szOfCellGrpOfSameType(tmp00);
3910 DAInt idInMsOfCellGrpOfSameType(tmp11);
3912 newm1->setName(getName());
3913 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3915 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3916 DAInt newFam=DataArrayInt::New();
3917 newFam->alloc(newm1->getNumberOfCells(),1);
3918 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3919 // Positive ID for family of nodes, negative for all the rest.
3921 if (m1->getMeshDimension() == 0)
3922 idd=getMaxFamilyId()+1;
3924 idd=getMinFamilyId()-1;
3925 int globStart=0,start=0,end,globEnd;
3926 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3927 for(int i=0;i<nbOfChunks;i++)
3929 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3930 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3932 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3933 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3934 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3939 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3943 newm1->setCoords(getCoords());
3944 setMeshAtLevel(-1,newm1);
3945 setFamilyFieldArr(-1,newFam);
3946 std::string grpName2(grpNameM1); grpName2+="_dup";
3947 addFamily(grpName2,idd);
3948 addFamilyOnGrp(grpName2,grpName2);
3953 int newNbOfNodes=getCoords()->getNumberOfTuples();
3954 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3955 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3956 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3961 _rev_num_coords = 0;
3962 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
3963 it != _ms.end(); it++)
3966 (*it)->_rev_num = 0;
3968 nodesDuplicated=nodeIdsToDuplicate.retn();
3969 cellsModified=cellsToModifyConn0.retn();
3970 cellsNotModified=cellsToModifyConn1.retn();
3973 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
3974 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
3977 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3978 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3979 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3981 * \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.
3982 * 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.
3984 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3986 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3987 std::vector<int> levs=getNonEmptyLevels();
3989 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3990 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3993 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3995 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3996 std::vector<int> code1=m->getDistributionOfTypes();
3997 end=PutInThirdComponentOfCodeOffset(code1,start);
3998 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3999 bool hasChanged=m->unPolyze();
4000 DataArrayInt *fake=0;
4001 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4002 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4004 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4007 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4008 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4010 MCAuto<DataArrayInt> famField2,numField2;
4011 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4012 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4013 setMeshAtLevel(*it,m);
4014 std::vector<int> code2=m->getDistributionOfTypes();
4015 end=PutInThirdComponentOfCodeOffset(code2,start);
4016 newCode.insert(newCode.end(),code2.begin(),code2.end());
4018 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4022 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4023 setFamilyFieldArr(*it,newFamField);
4027 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4028 setRenumFieldArr(*it,newNumField);
4033 newCode.insert(newCode.end(),code1.begin(),code1.end());
4039 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4040 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4041 o2nRenumCell=o2nRenumCellRet.retn();
4046 /*! \cond HIDDEN_ITEMS */
4047 struct MEDLoaderAccVisit1
4049 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4050 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4051 int _new_nb_of_nodes;
4056 * 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.
4057 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4058 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4059 * -1 values in returned array means that the corresponding old node is no more used.
4061 * \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
4062 * is modified in \a this.
4063 * \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
4066 DataArrayInt *MEDFileUMesh::zipCoords()
4068 const DataArrayDouble *coo(getCoords());
4070 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4071 int nbOfNodes(coo->getNumberOfTuples());
4072 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4073 std::vector<int> neLevs(getNonEmptyLevels());
4074 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4076 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4077 if(zeLev->isMeshStoredSplitByType())
4079 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4080 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4082 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4086 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4087 mesh->computeNodeIdsAlg(nodeIdsInUse);
4090 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4091 if(nbrOfNodesInUse==nbOfNodes)
4092 return 0;//no need to update _part_coords
4093 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4094 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4095 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4096 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4097 MCAuto<DataArrayInt> newFamCoords;
4098 MCAuto<DataArrayAsciiChar> newNameCoords;
4099 if((const DataArrayInt *)_fam_coords)
4100 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4101 MCAuto<DataArrayInt> newNumCoords;
4102 if((const DataArrayInt *)_num_coords)
4103 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4104 if((const DataArrayAsciiChar *)_name_coords)
4105 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4106 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4107 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4109 if((MEDFileUMeshSplitL1*)*it)
4111 (*it)->renumberNodesInConn(ret->begin());
4112 (*it)->setCoords(_coords);
4115 // updates _part_coords
4116 const PartDefinition *pc(_part_coords);
4119 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4120 _part_coords=tmpPD->composeWith(pc);
4126 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4127 * The extraction of \a this is specified by the extractDef \a input map.
4128 * This map tells for each level of cells, the cells kept in the extraction.
4130 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4131 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4133 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4135 std::vector<int> levs(getNonEmptyLevels());
4136 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4137 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4140 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4141 if((*it).second.isNull())
4142 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4145 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4147 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4148 throw INTERP_KERNEL::Exception(oss.str());
4150 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4151 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4152 mPart->computeNodeIdsAlg(fetchedNodes);
4154 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4158 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4160 * \return - a new reference of MEDFileUMesh
4161 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4163 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4165 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4166 std::vector<int> levs(getNonEmptyLevels());
4167 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4170 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4171 if((*it).second.isNull())
4172 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4175 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4177 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4178 throw INTERP_KERNEL::Exception(oss.str());
4180 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4181 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4182 ret->setMeshAtLevel((*it).first,mPart);
4183 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4186 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4187 ret->setFamilyFieldArr((*it).first,famPart);
4191 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4192 ret->setFamilyFieldArr((*it).first,numPart);
4195 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4196 if(it2!=extractDef.end())
4198 const DataArrayDouble *coo(ret->getCoords());
4200 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4201 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4202 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4203 ret->setCoords(cooPart);
4204 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4207 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4208 ret->setFamilyFieldArr(1,famPart);
4212 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4213 ret->setFamilyFieldArr(1,numPart);
4215 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4219 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4220 m->renumberNodesInConn(o2nNodes->begin());
4221 ret->setMeshAtLevel((*it3).first,m);
4228 * This method performs an extrusion along a path defined by \a m1D.
4229 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4230 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4231 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4232 * This method scans all levels in \a this
4233 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4235 * \param [in] m1D - the mesh defining the extrusion path.
4236 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4237 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4239 * \sa MEDCouplingUMesh::buildExtrudedMesh
4241 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4244 if(getMeshDimension()!=2)
4245 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4246 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4247 m1D->checkConsistencyLight();
4248 if(m1D->getMeshDimension()!=1)
4249 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4250 int nbRep(m1D->getNumberOfCells());
4251 std::vector<int> levs(getNonEmptyLevels());
4252 std::vector<std::string> grps(getGroupsNames());
4253 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4254 DataArrayDouble *coords(0);
4255 std::size_t nbOfLevsOut(levs.size()+1);
4256 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4257 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4259 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4260 item=item->clone(false);
4261 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4262 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4263 tmp->changeSpaceDimension(3+(*lev),0.);
4264 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4265 zeList.push_back(elt);
4267 coords=elt->getCoords();
4270 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4271 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4273 (*it)->setName(getName());
4274 (*it)->setCoords(coords);
4276 for(std::size_t ii=0;ii!=zeList.size();ii++)
4279 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4282 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4283 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4284 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4285 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4286 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4287 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4288 std::vector<const MEDCouplingUMesh *> elts(3);
4289 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4290 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4291 elt->setName(getName());
4294 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4295 ret->setMeshAtLevel(lev,elt);
4297 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4298 endLev=endLev->clone(false); endLev->setCoords(coords);
4299 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4300 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4301 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4302 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4303 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4304 endLev->setName(getName());
4305 ret->setMeshAtLevel(levs.back()-1,endLev);
4307 for(std::size_t ii=0;ii!=zeList.size();ii++)
4310 std::vector< MCAuto<DataArrayInt> > outGrps;
4311 std::vector< const DataArrayInt * > outGrps2;
4314 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4316 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4317 if(!grpArr->empty())
4319 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4320 int offset0(zeList[ii]->getNumberOfCells());
4321 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4322 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4323 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4324 grpArr2->setName(oss.str());
4325 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4326 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4327 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4328 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4333 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4335 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4336 if(!grpArr->empty())
4338 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4339 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4340 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4341 for(int iii=0;iii<nbRep;iii++)
4343 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4344 grpArrs2[iii]=grpArrs[iii];
4346 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4347 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4348 std::ostringstream grpName; grpName << *grp << "_extruded";
4349 grpArrExt->setName(grpName.str());
4350 outGrps.push_back(grpArrExt);
4351 outGrps2.push_back(grpArrExt);
4354 ret->setGroupsAtLevel(lev,outGrps2);
4356 std::vector< MCAuto<DataArrayInt> > outGrps;
4357 std::vector< const DataArrayInt * > outGrps2;
4358 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4360 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4361 if(grpArr1->empty())
4363 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4364 std::ostringstream grpName; grpName << *grp << "_top";
4365 grpArr2->setName(grpName.str());
4366 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4367 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4368 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4370 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4375 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4376 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4377 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4379 * \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
4380 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4381 * \param [in] eps - detection threshold for coordinates.
4382 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4384 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4386 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4389 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4390 int initialNbNodes(getNumberOfNodes());
4391 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4392 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4394 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4396 DataArrayDouble *zeCoords(m0->getCoords());
4397 ret->setMeshAtLevel(0,m0);
4398 std::vector<int> levs(getNonEmptyLevels());
4399 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4402 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4403 ret->setFamilyFieldArr(0,famFieldCpy);
4405 famField=getFamilyFieldAtLevel(1);
4408 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4409 fam->fillWithZero();
4410 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4411 ret->setFamilyFieldArr(1,fam);
4413 ret->copyFamGrpMapsFrom(*this);
4414 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4415 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4419 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4420 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4421 if(m1->getMeshDimension()!=0)
4424 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4425 }//kill unused notUsed var
4426 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4428 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4429 MCAuto<DataArrayInt> bSafe(b);
4432 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4433 throw INTERP_KERNEL::Exception(oss.str().c_str());
4435 b->applyLin(1,initialNbNodes);
4436 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4437 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4438 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4439 m1->renumberNodesInConn(renum->begin());
4441 m1->setCoords(zeCoords);
4442 ret->setMeshAtLevel(*lev,m1);
4443 famField=getFamilyFieldAtLevel(*lev);
4446 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4447 ret->setFamilyFieldArr(*lev,famFieldCpy);
4454 * This method converts all quadratic cells in \a this into linear cells.
4455 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4456 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4458 * \param [in] eps - detection threshold for coordinates.
4459 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4461 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4463 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4466 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4467 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4468 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4469 m0->convertQuadraticCellsToLinear();
4471 DataArrayDouble *zeCoords(m0->getCoords());
4472 ret->setMeshAtLevel(0,m0);
4473 std::vector<int> levs(getNonEmptyLevels());
4474 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4477 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4478 ret->setFamilyFieldArr(0,famFieldCpy);
4480 famField=getFamilyFieldAtLevel(1);
4483 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4484 ret->setFamilyFieldArr(1,fam);
4486 ret->copyFamGrpMapsFrom(*this);
4487 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4491 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4492 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4493 m1->convertQuadraticCellsToLinear();
4496 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4497 MCAuto<DataArrayInt> bSafe(b);
4500 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4501 throw INTERP_KERNEL::Exception(oss.str().c_str());
4503 m1->renumberNodesInConn(b->begin());
4504 m1->setCoords(zeCoords);
4505 ret->setMeshAtLevel(*lev,m1);
4506 famField=getFamilyFieldAtLevel(*lev);
4509 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4510 ret->setFamilyFieldArr(*lev,famFieldCpy);
4517 * Computes the symmetry of \a this.
4518 * \return a new object.
4520 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4522 MCAuto<MEDFileUMesh> ret(deepCopy());
4523 DataArrayDouble *myCoo(getCoords());
4526 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4527 ret->setCoordsForced(newCoo);
4532 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4535 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4536 std::size_t sz(meshes.size()),i(0);
4537 std::vector<const DataArrayDouble *> coos(sz);
4538 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4539 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4542 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4543 coos[i]=(*it)->getCoords();
4544 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4545 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4547 const MEDFileUMesh *ref(meshes[0]);
4548 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4549 std::vector<int> levs(ref->getNonEmptyLevels());
4550 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4551 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4552 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4553 std::map<std::string,int> map1;
4554 std::map<std::string, std::vector<std::string> > map2;
4555 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4557 if((*it)->getSpaceDimension()!=spaceDim)
4558 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4559 if((*it)->getMeshDimension()!=meshDim)
4560 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4561 if((*it)->getNonEmptyLevels()!=levs)
4562 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4563 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4565 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4566 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4567 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4568 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4570 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4571 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4572 map1[(*it3).first]=(*it3).second;
4573 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4574 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4575 map2[(*it4).first]=(*it4).second;
4577 // Easy part : nodes
4578 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4579 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4580 ret->setCoords(coo);
4581 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4583 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4584 ret->setFamilyFieldArr(1,fam_coo);
4586 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4588 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4589 ret->setRenumFieldArr(1,num_coo);
4592 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4594 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4595 if(it2==m_mesh.end())
4596 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4597 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4598 mesh->setCoords(coo); mesh->setName(ref->getName());
4599 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4600 ret->setMeshAtLevel(*it,mesh);
4601 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4602 if(it3!=m_fam.end())
4604 const std::vector<const DataArrayInt *>& fams((*it3).second);
4605 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4607 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4608 famm->renumberInPlace(renum->begin());
4609 ret->setFamilyFieldArr(*it,famm);
4612 if(it4!=m_renum.end())
4614 const std::vector<const DataArrayInt *>& renums((*it4).second);
4615 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4617 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4618 renumm->renumberInPlace(renum->begin());
4619 ret->setRenumFieldArr(*it,renumm);
4624 ret->setFamilyInfo(map1);
4625 ret->setGroupInfo(map2);
4626 ret->setName(ref->getName());
4630 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4632 if(getMeshDimension()!=3)
4633 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4634 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4635 if(m3D.isNull() || m2D.isNull())
4636 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4637 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4638 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4642 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4644 clearNonDiscrAttributes();
4645 forceComputationOfParts();
4646 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4647 std::vector<int> layer0;
4648 layer0.push_back(getAxisType());//0 i
4649 layer0.push_back(_order); //1 i
4650 layer0.push_back(_iteration);//2 i
4651 layer0.push_back(getSpaceDimension());//3 i
4652 tinyDouble.push_back(_time);//0 d
4653 tinyStr.push_back(_name);//0 s
4654 tinyStr.push_back(_desc_name);//1 s
4655 for(int i=0;i<getSpaceDimension();i++)
4656 tinyStr.push_back(_coords->getInfoOnComponent(i));
4657 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4658 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4660 tinyStr.push_back((*it).first);
4661 layer0.push_back((*it).second);
4663 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4664 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4666 layer0.push_back((int)(*it0).second.size());
4667 tinyStr.push_back((*it0).first);
4668 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4669 tinyStr.push_back(*it1);
4671 // sizeof(layer0)==4+aa+1+bb layer#0
4672 bigArrayD=_coords;// 0 bd
4673 bigArraysI.push_back(_fam_coords);// 0 bi
4674 bigArraysI.push_back(_num_coords);// 1 bi
4675 const PartDefinition *pd(_part_coords);
4677 layer0.push_back(-1);
4680 std::vector<int> tmp0;
4681 pd->serialize(tmp0,bigArraysI);
4682 tinyInt.push_back(tmp0.size());
4683 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4686 std::vector<int> layer1;
4687 std::vector<int> levs(getNonEmptyLevels());
4688 layer1.push_back((int)levs.size());// 0 i <- key
4689 layer1.insert(layer1.end(),levs.begin(),levs.end());
4690 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4692 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4693 lev->serialize(layer1,bigArraysI);
4695 // put layers all together.
4696 tinyInt.push_back(layer0.size());
4697 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4698 tinyInt.push_back(layer1.size());
4699 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4702 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4703 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4705 int sz0(tinyInt[0]);
4706 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4707 int sz1(tinyInt[sz0+1]);
4708 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4710 std::reverse(layer0.begin(),layer0.end());
4711 std::reverse(layer1.begin(),layer1.end());
4712 std::reverse(tinyDouble.begin(),tinyDouble.end());
4713 std::reverse(tinyStr.begin(),tinyStr.end());
4714 std::reverse(bigArraysI.begin(),bigArraysI.end());
4716 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4717 _order=layer0.back(); layer0.pop_back();
4718 _iteration=layer0.back(); layer0.pop_back();
4719 int spaceDim(layer0.back()); layer0.pop_back();
4720 _time=tinyDouble.back(); tinyDouble.pop_back();
4721 _name=tinyStr.back(); tinyStr.pop_back();
4722 _desc_name=tinyStr.back(); tinyStr.pop_back();
4723 _coords=bigArrayD; _coords->rearrange(spaceDim);
4724 for(int i=0;i<spaceDim;i++)
4726 _coords->setInfoOnComponent(i,tinyStr.back());
4729 int nbOfFams(layer0.back()); layer0.pop_back();
4731 for(int i=0;i<nbOfFams;i++)
4733 _families[tinyStr.back()]=layer0.back();
4734 tinyStr.pop_back(); layer0.pop_back();
4736 int nbGroups(layer0.back()); layer0.pop_back();
4738 for(int i=0;i<nbGroups;i++)
4740 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4741 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4742 std::vector<std::string> fams(nbOfFamsOnGrp);
4743 for(int j=0;j<nbOfFamsOnGrp;j++)
4745 fams[j]=tinyStr.back(); tinyStr.pop_back();
4747 _groups[grpName]=fams;
4749 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4750 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4752 int isPd(layer0.back()); layer0.pop_back();
4755 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4756 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4757 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4760 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4762 int nbLevs(layer1.back()); layer1.pop_back();
4763 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4765 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4766 _ms.resize(maxLev+1);
4767 for(int i=0;i<nbLevs;i++)
4771 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4776 * Adds a group of nodes to \a this mesh.
4777 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4778 * The ids should be sorted and different each other (MED file norm).
4780 * \warning this method can alter default "FAMILLE_ZERO" family.
4781 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4783 * \throw If the node coordinates array is not set.
4784 * \throw If \a ids == \c NULL.
4785 * \throw If \a ids->getName() == "".
4786 * \throw If \a ids does not respect the MED file norm.
4787 * \throw If a group with name \a ids->getName() already exists.
4789 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4791 const DataArrayDouble *coords(_coords);
4793 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4794 int nbOfNodes(coords->getNumberOfTuples());
4795 if(!((DataArrayInt *)_fam_coords))
4796 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4798 addGroupUnderground(true,ids,_fam_coords);
4802 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4804 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4805 * The ids should be sorted and different each other (MED file norm).
4807 * \warning this method can alter default "FAMILLE_ZERO" family.
4808 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4810 * \throw If the node coordinates array is not set.
4811 * \throw If \a ids == \c NULL.
4812 * \throw If \a ids->getName() == "".
4813 * \throw If \a ids does not respect the MED file norm.
4814 * \throw If a group with name \a ids->getName() already exists.
4816 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4818 std::vector<int> levs(getNonEmptyLevelsExt());
4819 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4821 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4822 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4824 if(meshDimRelToMaxExt==1)
4825 { addNodeGroup(ids); return ; }
4826 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4827 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4828 addGroupUnderground(false,ids,fam);
4832 * Changes a name of a family specified by its id.
4833 * \param [in] id - the id of the family of interest.
4834 * \param [in] newFamName - the new family name.
4835 * \throw If no family with the given \a id exists.
4837 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4839 std::string oldName=getFamilyNameGivenId(id);
4840 _families.erase(oldName);
4841 _families[newFamName]=id;
4845 * Removes a mesh of a given dimension.
4846 * \param [in] meshDimRelToMax - the relative dimension of interest.
4847 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4849 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4851 std::vector<int> levSet=getNonEmptyLevels();
4852 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4853 if(it==levSet.end())
4854 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4855 int pos=(-meshDimRelToMax);
4860 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4861 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4862 * \param [in] m - the new mesh to set.
4863 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4865 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4866 * another node coordinates array.
4867 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4868 * to the existing meshes of other levels of \a this mesh.
4870 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4872 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4873 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4877 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4878 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4879 * \param [in] m - the new mesh to set.
4880 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4881 * writing \a this mesh in a MED file.
4882 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4884 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4885 * another node coordinates array.
4886 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4887 * to the existing meshes of other levels of \a this mesh.
4889 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4891 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4892 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4895 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4897 dealWithTinyInfo(m);
4898 std::vector<int> levSet=getNonEmptyLevels();
4899 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4901 if((DataArrayDouble *)_coords==0)
4903 DataArrayDouble *c=m->getCoords();
4908 if(m->getCoords()!=_coords)
4909 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4910 int sz=(-meshDimRelToMax)+1;
4911 if(sz>=(int)_ms.size())
4913 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4917 return _ms[-meshDimRelToMax];
4921 * This method allows to set at once the content of different levels in \a this.
4922 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4924 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4925 * \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.
4926 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4928 * \throw If \a there is a null pointer in \a ms.
4929 * \sa MEDFileUMesh::setMeshAtLevel
4931 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4935 const MEDCouplingUMesh *mRef=ms[0];
4937 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4938 std::string name(mRef->getName());
4939 const DataArrayDouble *coo(mRef->getCoords());
4942 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4944 const MEDCouplingUMesh *cur(*it);
4946 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4947 if(coo!=cur->getCoords())
4948 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4949 int mdim=cur->getMeshDimension();
4950 zeDim=std::max(zeDim,mdim);
4951 if(s.find(mdim)!=s.end())
4952 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4954 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4956 int mdim=(*it)->getMeshDimension();
4957 setName((*it)->getName());
4958 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4964 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4965 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4966 * The given meshes must share the same node coordinates array.
4967 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4968 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4969 * create in \a this mesh.
4970 * \throw If \a ms is empty.
4971 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4972 * to the existing meshes of other levels of \a this mesh.
4973 * \throw If the meshes in \a ms do not share the same node coordinates array.
4974 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4975 * of the given meshes.
4976 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
4977 * \throw If names of some meshes in \a ms are equal.
4978 * \throw If \a ms includes a mesh with an empty name.
4980 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4983 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4984 int sz=(-meshDimRelToMax)+1;
4985 if(sz>=(int)_ms.size())
4987 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4988 DataArrayDouble *coo=checkMultiMesh(ms);
4989 if((DataArrayDouble *)_coords==0)
4995 if((DataArrayDouble *)_coords!=coo)
4996 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4997 std::vector<DataArrayInt *> corr;
4998 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4999 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5000 setMeshAtLevel(meshDimRelToMax,m,renum);
5001 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5002 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5006 * Creates groups at a given level in \a this mesh from a sequence of
5007 * meshes each representing a group.
5008 * The given meshes must share the same node coordinates array.
5009 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5010 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5011 * create in \a this mesh.
5012 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5014 * \throw If \a ms is empty.
5015 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5016 * to the existing meshes of other levels of \a this mesh.
5017 * \throw If the meshes in \a ms do not share the same node coordinates array.
5018 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5019 * of the given meshes.
5020 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5021 * \throw If names of some meshes in \a ms are equal.
5022 * \throw If \a ms includes a mesh with an empty name.
5024 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5027 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5028 int sz=(-meshDimRelToMax)+1;
5029 if(sz>=(int)_ms.size())
5031 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5032 DataArrayDouble *coo=checkMultiMesh(ms);
5033 if((DataArrayDouble *)_coords==0)
5039 if((DataArrayDouble *)_coords!=coo)
5040 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5041 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5042 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5044 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5046 DataArrayInt *arr=0;
5047 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5051 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5052 throw INTERP_KERNEL::Exception(oss.str().c_str());
5055 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5056 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5059 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5061 const DataArrayDouble *ret=ms[0]->getCoords();
5062 int mdim=ms[0]->getMeshDimension();
5063 for(unsigned int i=1;i<ms.size();i++)
5065 ms[i]->checkConsistencyLight();
5066 if(ms[i]->getCoords()!=ret)
5067 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5068 if(ms[i]->getMeshDimension()!=mdim)
5069 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5071 return const_cast<DataArrayDouble *>(ret);
5075 * Sets the family field of a given relative dimension.
5076 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5077 * the family field is set.
5078 * \param [in] famArr - the array of the family field.
5079 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5080 * \throw If \a famArr has an invalid size.
5082 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5084 if(meshDimRelToMaxExt==1)
5091 DataArrayDouble *coo(_coords);
5093 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5094 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5099 if(meshDimRelToMaxExt>1)
5100 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5101 int traducedRk=-meshDimRelToMaxExt;
5102 if(traducedRk>=(int)_ms.size())
5103 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5104 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5105 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5106 return _ms[traducedRk]->setFamilyArr(famArr);
5110 * Sets the optional numbers of mesh entities of a given dimension.
5111 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5112 * \param [in] renumArr - the array of the numbers.
5113 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5114 * \throw If \a renumArr has an invalid size.
5116 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5118 if(meshDimRelToMaxExt==1)
5126 DataArrayDouble *coo(_coords);
5128 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5129 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5130 renumArr->incrRef();
5131 _num_coords=renumArr;
5135 if(meshDimRelToMaxExt>1)
5136 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5137 int traducedRk=-meshDimRelToMaxExt;
5138 if(traducedRk>=(int)_ms.size())
5139 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5140 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5141 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5142 return _ms[traducedRk]->setRenumArr(renumArr);
5146 * Sets the optional names of mesh entities of a given dimension.
5147 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5148 * \param [in] nameArr - the array of the names.
5149 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5150 * \throw If \a nameArr has an invalid size.
5152 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5154 if(meshDimRelToMaxExt==1)
5161 DataArrayDouble *coo(_coords);
5163 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5164 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5166 _name_coords=nameArr;
5169 if(meshDimRelToMaxExt>1)
5170 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5171 int traducedRk=-meshDimRelToMaxExt;
5172 if(traducedRk>=(int)_ms.size())
5173 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5174 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5175 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5176 return _ms[traducedRk]->setNameArr(nameArr);
5179 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5181 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5182 if((const MEDFileUMeshSplitL1 *)(*it))
5183 (*it)->synchronizeTinyInfo(*this);
5187 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5189 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5191 DataArrayInt *arr=_fam_coords;
5193 arr->changeValue(oldId,newId);
5194 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5196 MEDFileUMeshSplitL1 *sp=(*it);
5199 sp->changeFamilyIdArr(oldId,newId);
5204 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5206 std::list< MCAuto<DataArrayInt> > ret;
5207 const DataArrayInt *da(_fam_coords);
5209 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5210 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5212 const MEDFileUMeshSplitL1 *elt(*it);
5215 da=elt->getFamilyField();
5217 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5223 void MEDFileUMesh::computeRevNum() const
5225 if((const DataArrayInt *)_num_coords)
5228 int maxValue=_num_coords->getMaxValue(pos);
5229 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5233 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5235 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5238 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5240 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5241 ret.push_back((const DataArrayInt *)_fam_nodes);
5242 ret.push_back((const DataArrayInt *)_num_nodes);
5243 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5244 ret.push_back((const DataArrayInt *)_fam_cells);
5245 ret.push_back((const DataArrayInt *)_num_cells);
5246 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5247 ret.push_back((const DataArrayInt *)_fam_faces);
5248 ret.push_back((const DataArrayInt *)_num_faces);
5249 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5250 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5251 ret.push_back((const DataArrayInt *)_rev_num_cells);
5252 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5256 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5258 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5259 if((const DataArrayInt *)_fam_nodes)
5261 int val=_fam_nodes->getMaxValue(tmp);
5262 ret=std::max(ret,std::abs(val));
5264 if((const DataArrayInt *)_fam_cells)
5266 int val=_fam_cells->getMaxValue(tmp);
5267 ret=std::max(ret,std::abs(val));
5269 if((const DataArrayInt *)_fam_faces)
5271 int val=_fam_faces->getMaxValue(tmp);
5272 ret=std::max(ret,std::abs(val));
5277 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5279 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5280 if((const DataArrayInt *)_fam_nodes)
5282 int val=_fam_nodes->getMaxValue(tmp);
5283 ret=std::max(ret,val);
5285 if((const DataArrayInt *)_fam_cells)
5287 int val=_fam_cells->getMaxValue(tmp);
5288 ret=std::max(ret,val);
5290 if((const DataArrayInt *)_fam_faces)
5292 int val=_fam_faces->getMaxValue(tmp);
5293 ret=std::max(ret,val);
5298 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5300 int ret=std::numeric_limits<int>::max(),tmp=-1;
5301 if((const DataArrayInt *)_fam_nodes)
5303 int val=_fam_nodes->getMinValue(tmp);
5304 ret=std::min(ret,val);
5306 if((const DataArrayInt *)_fam_cells)
5308 int val=_fam_cells->getMinValue(tmp);
5309 ret=std::min(ret,val);
5311 if((const DataArrayInt *)_fam_faces)
5313 int val=_fam_faces->getMinValue(tmp);
5314 ret=std::min(ret,val);
5319 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5321 if(!MEDFileMesh::isEqual(other,eps,what))
5323 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5326 what="Mesh types differ ! This is structured and other is NOT !";
5329 const DataArrayInt *famc1=_fam_nodes;
5330 const DataArrayInt *famc2=otherC->_fam_nodes;
5331 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5333 what="Mismatch of families arr on nodes ! One is defined and not other !";
5338 bool ret=famc1->isEqual(*famc2);
5341 what="Families arr on nodes differ !";
5346 famc2=otherC->_fam_cells;
5347 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5349 what="Mismatch of families arr on cells ! One is defined and not other !";
5354 bool ret=famc1->isEqual(*famc2);
5357 what="Families arr on cells differ !";
5362 famc2=otherC->_fam_faces;
5363 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5365 what="Mismatch of families arr on faces ! One is defined and not other !";
5370 bool ret=famc1->isEqual(*famc2);
5373 what="Families arr on faces differ !";
5378 famc2=otherC->_num_nodes;
5379 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5381 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5386 bool ret=famc1->isEqual(*famc2);
5389 what="Numbering arr on nodes differ !";
5394 famc2=otherC->_num_cells;
5395 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5397 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5402 bool ret=famc1->isEqual(*famc2);
5405 what="Numbering arr on cells differ !";
5410 famc2=otherC->_num_faces;
5411 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5413 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5418 bool ret=famc1->isEqual(*famc2);
5421 what="Numbering arr on faces differ !";
5425 const DataArrayAsciiChar *d1=_names_cells;
5426 const DataArrayAsciiChar *d2=otherC->_names_cells;
5427 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5429 what="Mismatch of naming arr on cells ! One is defined and not other !";
5434 bool ret=d1->isEqual(*d2);
5437 what="Naming arr on cells differ !";
5442 d2=otherC->_names_faces;
5443 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5445 what="Mismatch of naming arr on faces ! One is defined and not other !";
5450 bool ret=d1->isEqual(*d2);
5453 what="Naming arr on faces differ !";
5458 d2=otherC->_names_nodes;
5459 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5461 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5466 bool ret=d1->isEqual(*d2);
5469 what="Naming arr on nodes differ !";
5476 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5478 MEDFileMesh::clearNonDiscrAttributes();
5479 const DataArrayInt *tmp=_fam_nodes;
5481 (const_cast<DataArrayInt *>(tmp))->setName("");
5484 (const_cast<DataArrayInt *>(tmp))->setName("");
5487 (const_cast<DataArrayInt *>(tmp))->setName("");
5490 (const_cast<DataArrayInt *>(tmp))->setName("");
5493 (const_cast<DataArrayInt *>(tmp))->setName("");
5496 (const_cast<DataArrayInt *>(tmp))->setName("");
5500 * Returns ids of mesh entities contained in given families of a given dimension.
5501 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5503 * \param [in] fams - the names of the families of interest.
5504 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5505 * returned instead of ids.
5506 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5507 * numbers, if available and required, of mesh entities of the families. The caller
5508 * is to delete this array using decrRef() as it is no more needed.
5509 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5511 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5513 std::vector<int> famIds(getFamiliesIds(fams));
5514 switch(meshDimRelToMaxExt)
5518 if((const DataArrayInt *)_fam_nodes)
5520 MCAuto<DataArrayInt> da;
5522 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5524 da=_fam_nodes->findIdsEqualList(0,0);
5526 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5531 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5536 if((const DataArrayInt *)_fam_cells)
5538 MCAuto<DataArrayInt> da;
5540 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5542 da=_fam_cells->findIdsEqualList(0,0);
5544 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5549 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5554 if((const DataArrayInt *)_fam_faces)
5556 MCAuto<DataArrayInt> da;
5558 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5560 da=_fam_faces->findIdsEqualList(0,0);
5562 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5567 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5571 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5573 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5577 * Sets the family field of a given relative dimension.
5578 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5579 * the family field is set.
5580 * \param [in] famArr - the array of the family field.
5581 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5582 * \throw If \a famArr has an invalid size.
5583 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5585 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5587 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5589 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5590 switch(meshDimRelToMaxExt)
5594 int nbCells(mesh->getNumberOfCells());
5596 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5602 int nbNodes(mesh->getNumberOfNodes());
5604 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5610 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5612 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5617 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5624 * Sets the optional numbers of mesh entities of a given dimension.
5625 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5626 * \param [in] renumArr - the array of the numbers.
5627 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5628 * \throw If \a renumArr has an invalid size.
5629 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5631 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5633 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5635 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5636 switch(meshDimRelToMaxExt)
5640 int nbCells=mesh->getNumberOfCells();
5641 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5642 _num_cells=renumArr;
5647 int nbNodes=mesh->getNumberOfNodes();
5648 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5649 _num_nodes=renumArr;
5654 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5655 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5656 _num_faces=renumArr;
5660 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5663 renumArr->incrRef();
5667 * Sets the optional names of mesh entities of a given dimension.
5668 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5669 * \param [in] nameArr - the array of the names.
5670 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5671 * \throw If \a nameArr has an invalid size.
5673 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5675 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5677 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5678 switch(meshDimRelToMaxExt)
5682 int nbCells=mesh->getNumberOfCells();
5683 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5684 _names_cells=nameArr;
5689 int nbNodes=mesh->getNumberOfNodes();
5690 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5691 _names_nodes=nameArr;
5696 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5697 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5698 _names_cells=nameArr;
5701 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5708 * Adds a group of nodes to \a this mesh.
5709 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5710 * The ids should be sorted and different each other (MED file norm).
5712 * \warning this method can alter default "FAMILLE_ZERO" family.
5713 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5715 * \throw If the node coordinates array is not set.
5716 * \throw If \a ids == \c NULL.
5717 * \throw If \a ids->getName() == "".
5718 * \throw If \a ids does not respect the MED file norm.
5719 * \throw If a group with name \a ids->getName() already exists.
5721 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5727 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5729 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5730 * The ids should be sorted and different each other (MED file norm).
5732 * \warning this method can alter default "FAMILLE_ZERO" family.
5733 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5735 * \throw If the node coordinates array is not set.
5736 * \throw If \a ids == \c NULL.
5737 * \throw If \a ids->getName() == "".
5738 * \throw If \a ids does not respect the MED file norm.
5739 * \throw If a group with name \a ids->getName() already exists.
5741 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5743 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5744 addGroupUnderground(false,ids,fam);
5749 * Returns the family field for mesh entities of a given dimension.
5750 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5751 * \return const DataArrayInt * - the family field. It is an array of ids of families
5752 * each mesh entity belongs to. It can be \c NULL.
5753 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5755 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5757 switch(meshDimRelToMaxExt)
5766 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5771 * Returns the family field for mesh entities of a given dimension.
5772 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5773 * \return const DataArrayInt * - the family field. It is an array of ids of families
5774 * each mesh entity belongs to. It can be \c NULL.
5775 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5777 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5779 switch(meshDimRelToMaxExt)
5788 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5793 * Returns the optional numbers of mesh entities of a given dimension.
5794 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5795 * \return const DataArrayInt * - the array of the entity numbers.
5796 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5797 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5799 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5801 switch(meshDimRelToMaxExt)
5810 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5815 * Returns the optional numbers of mesh entities of a given dimension transformed using
5816 * DataArrayInt::invertArrayN2O2O2N().
5817 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5818 * \return const DataArrayInt * - the array of the entity numbers transformed using
5819 * DataArrayInt::invertArrayN2O2O2N().
5820 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5821 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5823 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5825 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5826 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5827 if(meshDimRelToMaxExt==0)
5829 if((const DataArrayInt *)_num_cells)
5832 int maxValue=_num_cells->getMaxValue(pos);
5833 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5834 return _rev_num_cells;
5837 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5841 if((const DataArrayInt *)_num_nodes)
5844 int maxValue=_num_nodes->getMaxValue(pos);
5845 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5846 return _rev_num_nodes;
5849 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5853 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5855 switch(meshDimRelToMaxExt)
5858 return _names_cells;
5860 return _names_nodes;
5862 return _names_faces;
5864 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5869 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5870 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5872 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5874 std::vector<int> ret(1);
5879 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5880 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5882 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5884 std::vector<int> ret(2);
5890 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5892 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5894 std::vector<int> ret;
5895 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5906 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5908 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5910 std::vector<int> ret;
5911 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5922 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5924 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5926 std::vector<int> ret;
5927 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5938 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5940 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5942 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5946 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5948 DataArrayInt *arr=_fam_nodes;
5950 arr->changeValue(oldId,newId);
5953 arr->changeValue(oldId,newId);
5956 arr->changeValue(oldId,newId);
5959 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5961 std::list< MCAuto<DataArrayInt> > ret;
5962 const DataArrayInt *da(_fam_nodes);
5964 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5967 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5970 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5974 void MEDFileStructuredMesh::deepCpyAttributes()
5976 if((const DataArrayInt*)_fam_nodes)
5977 _fam_nodes=_fam_nodes->deepCopy();
5978 if((const DataArrayInt*)_num_nodes)
5979 _num_nodes=_num_nodes->deepCopy();
5980 if((const DataArrayAsciiChar*)_names_nodes)
5981 _names_nodes=_names_nodes->deepCopy();
5982 if((const DataArrayInt*)_fam_cells)
5983 _fam_cells=_fam_cells->deepCopy();
5984 if((const DataArrayInt*)_num_cells)
5985 _num_cells=_num_cells->deepCopy();
5986 if((const DataArrayAsciiChar*)_names_cells)
5987 _names_cells=_names_cells->deepCopy();
5988 if((const DataArrayInt*)_fam_faces)
5989 _fam_faces=_fam_faces->deepCopy();
5990 if((const DataArrayInt*)_num_faces)
5991 _num_faces=_num_faces->deepCopy();
5992 if((const DataArrayAsciiChar*)_names_faces)
5993 _names_faces=_names_faces->deepCopy();
5994 if((const DataArrayInt*)_rev_num_nodes)
5995 _rev_num_nodes=_rev_num_nodes->deepCopy();
5996 if((const DataArrayInt*)_rev_num_cells)
5997 _rev_num_cells=_rev_num_cells->deepCopy();
6001 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
6003 * \return a pointer to cartesian mesh that need to be managed by the caller.
6004 * \warning the returned pointer has to be managed by the caller.
6008 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6009 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6010 * \param [in] renum - it must be \c false.
6011 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6012 * delete using decrRef() as it is no more needed.
6014 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6018 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6019 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6020 switch(meshDimRelToMax)
6026 return const_cast<MEDCouplingStructuredMesh *>(m);
6031 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6032 buildMinusOneImplicitPartIfNeeded();
6033 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6039 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6043 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6045 std::vector<int> ret;
6046 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6047 if(famCells && famCells->presenceOfValue(ret))
6049 if(famFaces && famFaces->presenceOfValue(ret))
6054 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6056 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6057 const DataArrayInt *famNodes(_fam_nodes);
6058 if(famNodes && famNodes->presenceOfValue(ret))
6064 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6065 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6066 * \return int - the number of entities.
6067 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6069 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6071 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6073 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6074 switch(meshDimRelToMaxExt)
6077 return cmesh->getNumberOfCells();
6079 return cmesh->getNumberOfNodes();
6081 return cmesh->getNumberOfCellsOfSubLevelMesh();
6083 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6087 int MEDFileStructuredMesh::getNumberOfNodes() const
6089 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6091 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6092 return cmesh->getNumberOfNodes();
6095 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6097 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6099 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6100 switch(meshDimRelToMaxExt)
6103 return cmesh->getNumberOfCells();
6105 return cmesh->getNumberOfCellsOfSubLevelMesh();
6107 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6111 bool MEDFileStructuredMesh::hasImplicitPart() const
6117 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6119 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6121 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6122 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6125 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6126 if(cm.getReverseExtrudedType()!=gt)
6127 throw INTERP_KERNEL::Exception(MSG);
6128 buildImplicitPart();
6129 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6133 if(gt!=zeFaceMesh->getCellModelEnum())
6134 throw INTERP_KERNEL::Exception(MSG);
6135 return zeFaceMesh->getNumberOfCells();
6139 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6141 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6143 buildImplicitPart();
6146 void MEDFileStructuredMesh::buildImplicitPart() const
6148 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6150 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6151 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6154 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6156 _faces_if_necessary=0;
6160 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6161 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6163 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6165 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6168 return _faces_if_necessary;
6171 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6173 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6175 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6176 switch(meshDimRelToMax)
6180 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6185 int mdim(cmesh->getMeshDimension());
6187 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6188 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6192 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6196 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6198 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6201 return getNumberOfCellsAtLevel(0);
6204 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6206 if(st.getNumberOfItems()!=1)
6207 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 !");
6208 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6209 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6210 if(getNumberOfNodes()!=(int)nodesFetched.size())
6211 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6212 if(st[0].getPflName().empty())
6214 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6217 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6218 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6219 int sz(nodesFetched.size());
6220 for(const int *work=arr->begin();work!=arr->end();work++)
6222 std::vector<int> conn;
6223 cmesh->getNodeIdsOfCell(*work,conn);
6224 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6225 if(*it>=0 && *it<sz)
6226 nodesFetched[*it]=true;
6228 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6232 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6234 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6238 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6239 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6241 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6242 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6244 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6247 if(!mrs || mrs->isCellFamilyFieldReading())
6249 famCells=DataArrayInt::New();
6250 famCells->alloc(nbOfElt,1);
6251 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6254 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6257 if(!mrs || mrs->isCellNumFieldReading())
6259 numCells=DataArrayInt::New();
6260 numCells->alloc(nbOfElt,1);
6261 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6264 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6267 if(!mrs || mrs->isCellNameFieldReading())
6269 namesCells=DataArrayAsciiChar::New();
6270 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6271 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6272 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6277 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6279 setName(strm->getName());
6280 setDescription(strm->getDescription());
6281 setUnivName(strm->getUnivName());
6282 setIteration(strm->getIteration());
6283 setOrder(strm->getOrder());
6284 setTimeValue(strm->getTime());
6285 setTimeUnit(strm->getTimeUnit());
6286 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6287 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6288 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6291 if(!mrs || mrs->isNodeFamilyFieldReading())
6293 int nbNodes(getNumberOfNodes());
6295 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6296 _fam_nodes=DataArrayInt::New();
6297 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6298 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...
6299 _fam_nodes->fillWithZero();
6300 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6303 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6306 if(!mrs || mrs->isNodeNumFieldReading())
6308 _num_nodes=DataArrayInt::New();
6309 _num_nodes->alloc(nbOfElt,1);
6310 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6313 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6316 if(!mrs || mrs->isNodeNameFieldReading())
6318 _names_nodes=DataArrayAsciiChar::New();
6319 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6320 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6321 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6324 int meshDim(getStructuredMesh()->getMeshDimension());
6325 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6327 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6330 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6332 int meshDim(getStructuredMesh()->getMeshDimension());
6333 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6335 if((const DataArrayInt *)_fam_cells)
6336 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6337 if((const DataArrayInt *)_fam_faces)
6338 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6339 if((const DataArrayInt *)_fam_nodes)
6340 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6341 if((const DataArrayInt *)_num_cells)
6342 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6343 if((const DataArrayInt *)_num_faces)
6344 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6345 if((const DataArrayInt *)_num_nodes)
6346 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6347 if((const DataArrayAsciiChar *)_names_cells)
6349 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6351 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6352 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6353 throw INTERP_KERNEL::Exception(oss.str().c_str());
6355 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6357 if((const DataArrayAsciiChar *)_names_faces)
6359 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6361 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6362 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6363 throw INTERP_KERNEL::Exception(oss.str().c_str());
6365 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6367 if((const DataArrayAsciiChar *)_names_nodes)
6369 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6371 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6372 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6373 throw INTERP_KERNEL::Exception(oss.str().c_str());
6375 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6378 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6382 * Returns an empty instance of MEDFileCMesh.
6383 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6384 * mesh using decrRef() as it is no more needed.
6386 MEDFileCMesh *MEDFileCMesh::New()
6388 return new MEDFileCMesh;
6392 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6393 * file. The first mesh in the file is loaded.
6394 * \param [in] fileName - the name of MED file to read.
6395 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6396 * mesh using decrRef() as it is no more needed.
6397 * \throw If the file is not readable.
6398 * \throw If there is no meshes in the file.
6399 * \throw If the mesh in the file is not a Cartesian one.
6401 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6403 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6406 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6407 throw INTERP_KERNEL::Exception(oss.str().c_str());
6409 MEDFileUtilities::CheckFileForRead(fileName);
6410 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6412 MEDCoupling::MEDCouplingMeshType meshType;
6414 MEDCoupling::MEDCouplingAxisType dummy3;
6415 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6416 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
6420 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6421 * file. The mesh to load is specified by its name and numbers of a time step and an
6423 * \param [in] fileName - the name of MED file to read.
6424 * \param [in] mName - the name of the mesh to read.
6425 * \param [in] dt - the number of a time step.
6426 * \param [in] it - the number of an iteration.
6427 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6428 * mesh using decrRef() as it is no more needed.
6429 * \throw If the file is not readable.
6430 * \throw If there is no mesh with given attributes in the file.
6431 * \throw If the mesh in the file is not a Cartesian one.
6433 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6435 MEDFileUtilities::CheckFileForRead(fileName);
6436 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6437 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6440 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6442 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6445 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6447 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6448 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6453 * Returns the dimension on cells in \a this mesh.
6454 * \return int - the mesh dimension.
6455 * \throw If there are no cells in this mesh.
6457 int MEDFileCMesh::getMeshDimension() const
6459 if(!((const MEDCouplingCMesh*)_cmesh))
6460 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6461 return _cmesh->getMeshDimension();
6465 * Returns the dimension on nodes in \a this mesh.
6466 * \return int - the space dimension.
6467 * \throw If there are no cells in this mesh.
6469 int MEDFileCMesh::getSpaceDimension() const
6471 if(!((const MEDCouplingCMesh*)_cmesh))
6472 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6473 return _cmesh->getSpaceDimension();
6477 * Returns a string describing \a this mesh.
6478 * \return std::string - the mesh information string.
6480 std::string MEDFileCMesh::simpleRepr() const
6482 return MEDFileStructuredMesh::simpleRepr();
6486 * Returns a full textual description of \a this mesh.
6487 * \return std::string - the string holding the mesh description.
6489 std::string MEDFileCMesh::advancedRepr() const
6491 return simpleRepr();
6494 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6496 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6500 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6502 return new MEDFileCMesh;
6505 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6507 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6508 ret->deepCpyEquivalences(*this);
6509 if((const MEDCouplingCMesh*)_cmesh)
6510 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6511 ret->deepCpyAttributes();
6516 * Checks if \a this and another mesh are equal.
6517 * \param [in] other - the mesh to compare with.
6518 * \param [in] eps - a precision used to compare real values.
6519 * \param [in,out] what - the string returning description of unequal data.
6520 * \return bool - \c true if the meshes are equal, \c false, else.
6522 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6524 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6526 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6529 what="Mesh types differ ! This is cartesian and other is NOT !";
6532 clearNonDiscrAttributes();
6533 otherC->clearNonDiscrAttributes();
6534 const MEDCouplingCMesh *coo1=_cmesh;
6535 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6536 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6538 what="Mismatch of cartesian meshes ! One is defined and not other !";
6543 bool ret=coo1->isEqual(coo2,eps);
6546 what="cartesian meshes differ !";
6554 * Clears redundant attributes of incorporated data arrays.
6556 void MEDFileCMesh::clearNonDiscrAttributes() const
6558 MEDFileStructuredMesh::clearNonDiscrAttributes();
6559 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6562 MEDFileCMesh::MEDFileCMesh()
6566 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6569 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6571 catch(INTERP_KERNEL::Exception& e)
6576 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6578 MEDCoupling::MEDCouplingMeshType meshType;
6581 MEDCoupling::MEDCouplingAxisType axType;
6582 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6583 if(meshType!=CARTESIAN)
6585 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6586 throw INTERP_KERNEL::Exception(oss.str().c_str());
6588 MEDFileCMeshL2 loaderl2;
6589 loaderl2.loadAll(fid,mid,mName,dt,it);
6590 setAxisType(axType);
6591 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6594 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6598 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6599 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6601 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6603 synchronizeTinyInfoOnLeaves();
6607 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6609 synchronizeTinyInfoOnLeaves();
6614 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6615 * \param [in] m - the new MEDCouplingCMesh to refer to.
6616 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6619 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6621 dealWithTinyInfo(m);
6627 MEDFileMesh *MEDFileCMesh::cartesianize() const
6629 if(getAxisType()==AX_CART)
6632 return const_cast<MEDFileCMesh *>(this);
6636 const MEDCouplingCMesh *cmesh(getMesh());
6638 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6639 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6640 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6641 clmesh->setCoords(coords);
6642 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6643 ret->MEDFileStructuredMesh::operator=(*this);
6644 ret->setMesh(clmesh);
6645 ret->setAxisType(AX_CART);
6650 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6652 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6653 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6654 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6655 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6656 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6657 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6658 int spaceDim(_cmesh->getSpaceDimension());
6659 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6660 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6661 for(int i=0;i<spaceDim;i++)
6663 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6665 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6666 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
6667 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
6669 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6671 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6672 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6673 for(int i=0;i<spaceDim;i++)
6675 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6676 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6679 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6680 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6683 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6685 const MEDCouplingCMesh *cmesh=_cmesh;
6688 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6689 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6690 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6691 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6694 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6696 return new MEDFileCurveLinearMesh;
6699 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6701 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6704 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6705 throw INTERP_KERNEL::Exception(oss.str().c_str());
6707 MEDFileUtilities::CheckFileForRead(fileName);
6708 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6710 MEDCoupling::MEDCouplingMeshType meshType;
6711 MEDCoupling::MEDCouplingAxisType dummy3;
6713 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6714 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6717 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6719 MEDFileUtilities::CheckFileForRead(fileName);
6720 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6721 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6724 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6726 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6729 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6731 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6732 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6736 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6738 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6742 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6744 return new MEDFileCurveLinearMesh;
6747 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6749 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6750 ret->deepCpyEquivalences(*this);
6751 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6752 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6753 ret->deepCpyAttributes();
6757 int MEDFileCurveLinearMesh::getMeshDimension() const
6759 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6760 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6761 return _clmesh->getMeshDimension();
6764 std::string MEDFileCurveLinearMesh::simpleRepr() const
6766 return MEDFileStructuredMesh::simpleRepr();
6769 std::string MEDFileCurveLinearMesh::advancedRepr() const
6771 return simpleRepr();
6774 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6776 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6778 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6781 what="Mesh types differ ! This is curve linear and other is NOT !";
6784 clearNonDiscrAttributes();
6785 otherC->clearNonDiscrAttributes();
6786 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6787 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6788 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6790 what="Mismatch of curve linear meshes ! One is defined and not other !";
6795 bool ret=coo1->isEqual(coo2,eps);
6798 what="curve linear meshes differ !";
6805 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6807 MEDFileStructuredMesh::clearNonDiscrAttributes();
6808 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6811 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6813 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6816 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6817 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6818 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6819 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6822 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6824 synchronizeTinyInfoOnLeaves();
6828 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6830 dealWithTinyInfo(m);
6836 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6838 if(getAxisType()==AX_CART)
6841 return const_cast<MEDFileCurveLinearMesh *>(this);
6845 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6847 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6848 const DataArrayDouble *coords(mesh->getCoords());
6850 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6851 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6852 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6853 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6854 mesh2->setCoords(coordsCart);
6855 ret->setMesh(mesh2);
6856 ret->setAxisType(AX_CART);
6861 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6863 synchronizeTinyInfoOnLeaves();
6867 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6871 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6874 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6876 catch(INTERP_KERNEL::Exception& e)
6881 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
6883 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6884 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6885 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6886 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6887 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6888 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6889 int spaceDim=_clmesh->getSpaceDimension();
6890 int meshDim=_clmesh->getMeshDimension();
6891 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6892 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6893 const DataArrayDouble *coords=_clmesh->getCoords();
6895 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
6896 for(int i=0;i<spaceDim;i++)
6898 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6900 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6901 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
6902 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
6904 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6906 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6907 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6908 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6909 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6911 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6913 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6914 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6917 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6919 MEDCoupling::MEDCouplingMeshType meshType;
6922 MEDCoupling::MEDCouplingAxisType axType;
6923 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6924 setAxisType(axType);
6925 if(meshType!=CURVE_LINEAR)
6927 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6928 throw INTERP_KERNEL::Exception(oss.str().c_str());
6930 MEDFileCLMeshL2 loaderl2;
6931 loaderl2.loadAll(fid,mid,mName,dt,it);
6932 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6935 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6938 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6940 return new MEDFileMeshMultiTS;
6943 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6945 return new MEDFileMeshMultiTS(fileName);
6948 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6950 return new MEDFileMeshMultiTS(fileName,mName);
6953 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
6955 MCAuto<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6956 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6958 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6959 if((const MEDFileMesh *)*it)
6960 meshOneTs[i]=(*it)->deepCopy();
6961 ret->_mesh_one_ts=meshOneTs;
6965 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6967 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
6970 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6972 std::vector<const BigMemoryObject *> ret;
6973 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6974 ret.push_back((const MEDFileMesh *)*it);
6978 std::string MEDFileMeshMultiTS::getName() const
6980 if(_mesh_one_ts.empty())
6981 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6982 return _mesh_one_ts[0]->getName();
6985 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6987 std::string oldName(getName());
6988 std::vector< std::pair<std::string,std::string> > v(1);
6989 v[0].first=oldName; v[0].second=newMeshName;
6993 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6996 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6998 MEDFileMesh *cur(*it);
7000 ret=cur->changeNames(modifTab) || ret;
7005 void MEDFileMeshMultiTS::cartesianizeMe()
7007 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7009 MEDFileMesh *cur(*it);
7012 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7018 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7020 if(_mesh_one_ts.empty())
7021 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7022 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7025 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7028 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7029 _mesh_one_ts.resize(1);
7030 mesh1TimeStep->incrRef();
7031 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7032 _mesh_one_ts[0]=mesh1TimeStep;
7035 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7037 if ( MEDFileMesh* m = getOneTimeStep() )
7038 return m->getJoints();
7043 * \brief Set Joints that are common to all time-stamps
7045 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7047 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7049 (*it)->setJoints( joints );
7053 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7055 MEDFileJoints *joints(getJoints());
7056 bool jointsWritten(false);
7058 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7060 if ( jointsWritten )
7061 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7063 jointsWritten = true;
7065 (*it)->copyOptionsFrom(*this);
7066 (*it)->writeLL(fid);
7069 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7072 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
7074 MEDFileJoints* joints = 0;
7075 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7077 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7078 joints = getOneTimeStep()->getJoints();
7081 _mesh_one_ts.clear(); //for the moment to be improved
7082 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
7085 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7089 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
7092 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
7095 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
7096 throw INTERP_KERNEL::Exception(oss.str().c_str());
7098 MEDFileUtilities::CheckFileForRead(fileName);
7099 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
7101 MEDCoupling::MEDCouplingMeshType meshType;
7103 MEDCoupling::MEDCouplingAxisType dummy3;
7104 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7105 loadFromFile(fileName,ms.front());
7107 catch(INTERP_KERNEL::Exception& e)
7112 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
7115 loadFromFile(fileName,mName);
7117 catch(INTERP_KERNEL::Exception& e)
7122 MEDFileMeshes *MEDFileMeshes::New()
7124 return new MEDFileMeshes;
7127 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7129 return new MEDFileMeshes(fileName);
7132 void MEDFileMeshes::writeLL(med_idt fid) const
7134 checkConsistencyLight();
7135 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7137 (*it)->copyOptionsFrom(*this);
7138 (*it)->writeLL(fid);
7142 // MEDFileMeshes::writ checkConsistencyLight();
7144 int MEDFileMeshes::getNumberOfMeshes() const
7146 return _meshes.size();
7149 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7151 return new MEDFileMeshesIterator(this);
7154 /** Return a borrowed reference (caller is not responsible) */
7155 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7157 if(i<0 || i>=(int)_meshes.size())
7159 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7160 throw INTERP_KERNEL::Exception(oss.str().c_str());
7162 return _meshes[i]->getOneTimeStep();
7165 /** Return a borrowed reference (caller is not responsible) */
7166 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7168 std::vector<std::string> ms=getMeshesNames();
7169 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7172 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7173 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7174 throw INTERP_KERNEL::Exception(oss.str().c_str());
7176 return getMeshAtPos((int)std::distance(ms.begin(),it));
7179 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7181 std::vector<std::string> ret(_meshes.size());
7183 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7185 const MEDFileMeshMultiTS *f=(*it);
7188 ret[i]=f->getName();
7192 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7193 throw INTERP_KERNEL::Exception(oss.str().c_str());
7199 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7202 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7204 MEDFileMeshMultiTS *cur(*it);
7206 ret=cur->changeNames(modifTab) || ret;
7211 void MEDFileMeshes::cartesianizeMe()
7213 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7215 MEDFileMeshMultiTS *cur(*it);
7217 cur->cartesianizeMe();
7221 void MEDFileMeshes::resize(int newSize)
7223 _meshes.resize(newSize);
7226 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7229 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7230 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7231 elt->setOneTimeStep(mesh);
7232 _meshes.push_back(elt);
7235 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7238 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7239 if(i>=(int)_meshes.size())
7240 _meshes.resize(i+1);
7241 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7242 elt->setOneTimeStep(mesh);
7246 void MEDFileMeshes::destroyMeshAtPos(int i)
7248 if(i<0 || i>=(int)_meshes.size())
7250 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7251 throw INTERP_KERNEL::Exception(oss.str().c_str());
7253 _meshes.erase(_meshes.begin()+i);
7256 void MEDFileMeshes::loadFromFile(const std::string& fileName)
7258 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
7260 _meshes.resize(ms.size());
7261 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7262 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
7265 MEDFileMeshes::MEDFileMeshes()
7269 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
7272 loadFromFile(fileName);
7274 catch(INTERP_KERNEL::Exception& /*e*/)
7278 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7280 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7282 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7283 if((const MEDFileMeshMultiTS *)*it)
7284 meshes[i]=(*it)->deepCopy();
7285 MCAuto<MEDFileMeshes> ret=MEDFileMeshes::New();
7286 ret->_meshes=meshes;
7290 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7292 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7295 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7297 std::vector<const BigMemoryObject *> ret;
7298 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7299 ret.push_back((const MEDFileMeshMultiTS *)*it);
7303 std::string MEDFileMeshes::simpleRepr() const
7305 std::ostringstream oss;
7306 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7307 simpleReprWithoutHeader(oss);
7311 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7313 int nbOfMeshes=getNumberOfMeshes();
7314 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7315 std::vector<std::string> mns=getMeshesNames();
7316 for(int i=0;i<nbOfMeshes;i++)
7317 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7320 void MEDFileMeshes::checkConsistencyLight() const
7322 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7324 std::set<std::string> s;
7325 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7327 const MEDFileMeshMultiTS *elt=(*it);
7330 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7331 throw INTERP_KERNEL::Exception(oss.str().c_str());
7333 std::size_t sz=s.size();
7334 s.insert(std::string((*it)->getName()));
7337 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7338 throw INTERP_KERNEL::Exception(oss.str().c_str());
7343 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7348 _nb_iter=ms->getNumberOfMeshes();
7352 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7356 MEDFileMesh *MEDFileMeshesIterator::nextt()
7358 if(_iter_id<_nb_iter)
7360 MEDFileMeshes *ms(_ms);
7362 return ms->getMeshAtPos(_iter_id++);